/* ============================================================
   视界引擎 · 「鎏金胶片 Ciné Noir」设计系统 v4
   单一令牌层 + 单一外壳(全站一条顶栏) + 去重叠规则
   —— v4 重写:合并 v3 / v17 与历轮增量补丁,消除同选择器重复定义、
      !important 压制链与浅色模式语法残留;装饰收敛,层级由令牌驱动。
   目录
     1 令牌  2 基础  3 氛围  4 外壳与顶栏  5 弹层  6 按钮
     7 表单  8 卡片与网格  9 媒体卡  10 标签/状态/进度  11 表格
     12 空态与加载  13 弹窗/Toast/右键菜单/⌘K  14 登录页
     15 页面头与通用布局  16 首页  17 项目列表  18 分集工作台
     19 分镜工作台  20 资产库  21 风格库  22 AI 生图  23 后台管理
     24 积分中心与成本  25 成果查看器  26 占位符链接  27 动效
     28 响应式  29 浅色模式
   ============================================================ */

/* ---------- 1. 令牌 ---------- */
:root {
  color-scheme: dark;

  /* 画布与表面:页面 / 卡片 / 卡内 三级 */
  --bg: #0b0a08;
  --bg-deep: #070605;
  --surface: #14110d;
  --surface-2: #1a1610;
  --surface-3: #221d15;
  --surface-hover: rgba(227, 180, 94, .06);
  /* 「下沉」面:图片还没出来时露出的占位底。深色靠比表面更亮一档,浅色靠比表面更暗一档,
     所以这个关系必须能翻 —— 写成 --surface-3 的别名,浅色单独给一个更深的值。 */
  --surface-sunk: var(--surface-3);
  --line: rgba(217, 189, 130, .14);
  --line-strong: rgba(217, 189, 130, .30);
  --line-faint: rgba(255, 255, 255, .06);
  /* 薄雾底色:深色是「表面上的白雾」,浅色翻成「表面上的墨雾」。写成 rgba(var(--film), a)
     而不是直接 rgba(255,255,255,a),是为了每条规则保留自己的浓度,换主题时不会「白上加白」。 */
  --film: 255, 255, 255;

  /* 文字 */
  --ink: #f1ead9;
  --ink-2: #a89e88;
  --ink-3: #8b8171;

  /* 品牌金 —— *-rgb 是同一批色的 RGB 三元组形态,供 rgba(var(--accent-rgb), a) 使用:
     装饰金雾/描边/聚焦环全靠它,换主题时整族翻转,浓度逐条保留。 */
  --accent-rgb: 227, 180, 94;
  --accent-hi-rgb: 239, 202, 133;
  --accent-deep-rgb: 192, 138, 48;
  --gold: #e3b45e;
  --gold-soft: #f0d49a;
  --gold-deep: #b8842e;
  --gold-fill: #f5d07e;
  --gold-fill-h: #edb746;
  --gold-fill-a: #f5d07e;
  --gold-ink: #191307;
  /* 小号金色文字专用:与装饰金分开,保证 11-13px 下仍达 4.5:1 */
  --gold-text: #e3b45e;
  --grad-gold: linear-gradient(115deg, #f4dcab 8%, #e3b45e 52%, #b8842e 96%);

  /* 语义色(--ok-ink / --warn-ink / --danger-ink 是「印在语义色块上的字色」,浅色翻白字) */
  --ok-ink: #04120b;
  --warn-ink: #1a1400;
  --danger-ink: #2a0705;
  --ok: #41cf90;
  --warn: #fbbf24;
  --danger: #f0544c;
  --info: #7aa7d9;
  /* 语义色的 RGB 三元组:底纹/描边一律写 rgba(var(--ok-rgb), .14),不再把某套主题的
     色板字面值(.status-completed 的 65,207,144 之类)写死进组件 —— 那正是浅色下
     「控件还是旧配色」的来源。深色取值与历史字面值逐位相同,浅色整族翻成自己那套。 */
  --ok-rgb: 65, 207, 144;
  --warn-rgb: 251, 191, 36;
  --danger-rgb: 240, 84, 76;
  --info-rgb: 122, 167, 217;
  /* 「进行中 / 待处理」不是警告,是状态。深色沿用琥珀(与鎏金同族),浅色走主色蓝。
     四件套分别对应:实底色 / 实底上的字 / 淡底上的字 / 淡底配方。 */
  --proc: var(--warn);
  --proc-ink: var(--warn-ink);
  --proc-text: var(--warn);
  --proc-soft: rgba(var(--warn-rgb), .12);
  /* 压在「占位灰块」(还没出图)上的角标:深色是深底浮层,浅色该是白底药丸 */
  --flag-idle: rgba(var(--scrim-rgb), .78);
  --flag-idle-ink: var(--scrim-ink);
  --flag-idle-line: var(--scrim-line);

  /* 字号阶:全站只用这 8 档 */
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-md: 13px;
  --fs-lg: 14px;
  --fs-xl: 17px;
  --fs-2xl: 22px;
  --fs-3xl: 28px;

  /* 间距阶 */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;

  /* 圆角 / 控件高度 / 微间距 —— 全站只用这几档。--r-xs / --h-2xs / --h-xs / --sq-* / --gap-xs
     用来收编历史上散落的 6·7px 圆角、22·26·28px 控件高、5·6·7px 微间距(31·需求三十一)。 */
  --r-xs: 6px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-full: 999px;
  --h-2xs: 22px; --h-xs: 28px; --h-sm: 30px; --h-md: 36px; --h-lg: 44px;
  --sq-sm: 26px; --sq-md: 30px;                        /* 方形图标按钮两档 */
  --gap-xs: 6px;                                       /* 图标与文字、芯片之间 */

  /* 压在图片 / 视频上的浮层三件套:底色 / 字色 / 描边,换主题只翻这一处。
     --scrim-line 取强档:角标本身只有 20~28px,描边弱一档(.14)在深底上就等于没有。 */
  --scrim-rgb: 7, 6, 4;
  --scrim-ink: var(--ink);
  --scrim-line: var(--line-strong);
  /* 浮层上唯一允许出现的强调色(如参考资产的来源角标):深色是鎏金,浅色下金已退出,用白 */
  --scrim-accent: var(--gold);

  /* 选中态分两级:强(芯片「就是这一个」)与弱(导航 / 工具条 / 树目的当前项)。
     深色下强的是鎏金实底、弱的是悬停雾;浅色下两级收敛成同一种淡蓝。 */
  --sel-fill: var(--gold-fill);
  --sel-ink: var(--gold-ink);
  --sel-line: transparent;
  --sel-soft: var(--surface-hover);
  --sel-soft-ink: var(--gold-text);
  --sel-soft-line: var(--line-strong);
  --sel-ring: 0 0 0 1px var(--gold);                   /* 卡片被选中:描边 + 一圈同色环 */
  --ring: 0 0 0 3px rgba(var(--accent-rgb), .14);      /* 唯一的聚焦环配方 */

  /* 空间与层级令牌(深色沿用原值,浅色靠它们把「疏朗」拉开) */
  --gap: var(--sp-4);            /* 卡片网格间距 */
  --gap-sm: var(--sp-3);         /* 统计卡 / 芯片行间距 */
  --pad-card: var(--sp-5);       /* 卡片内白 */
  --pad-card-sm: var(--sp-4) var(--sp-5);
  --row-py: 11px;                /* 表格行高 */
  --head-py: 10px;
  --pad-page: var(--sp-6);       /* 页头上方留白 */
  --fs-page-title: var(--fs-xl);
  --card-shadow: none;           /* 深色靠描边分层,浅色靠影子浮起 */
  --pl-name-fs: 13.5px;          /* [占位符] 芯片内的资产名 */
  --media-h: 180px;            /* 成果卡媒体框:等高裁切,比例靠角标说明 */
  --card-min: 220px;           /* 卡片网格最小卡宽 —— JS 侧要按同一算式算列数 */
  --ig-card-min: 244px;

  /* 阴影 */
  --elev-1: 0 1px 2px rgba(0, 0, 0, .3);
  --elev-2: 0 8px 24px rgba(4, 3, 2, .4);
  --elev-3: 0 20px 52px rgba(4, 3, 2, .58);
  --glow: 0 6px 20px rgba(227, 180, 94, .12);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --display: Georgia, "Times New Roman", "Songti SC", "STSong", serif;
  --mono: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  --topbar-h: 64px;
  /* 内容宽度跟随视口(27·3:大屏两侧留白过多),只保留一个可读性上限 */
  --content-w: min(1840px, 100%);
}

/* 工作台与弹窗共用的一份作用域令牌(历史 ws-* 变量名保留,取值统一指向主令牌) */
.ws, #modalRoot {
  --ws-gold: var(--gold);
  --ws-panel: var(--surface);
  --ws-panel-2: var(--surface-2);
  --ws-line: var(--line);
  --ws-gold-line: var(--line-strong);
  --ws-dim: var(--ink-2);
  --ws-faint: var(--ink-3);
  --ws-ink: var(--gold-ink);
}

/* ---------- 2. 基础 ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
html { background: var(--bg-deep); }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs-md);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--ok); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; color: inherit; }
img, video { display: block; }
::selection { background: rgba(227, 180, 94, .8); color: #171208; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 4px; }
.hidden { display: none !important; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #3a3222; border-radius: var(--r-full); border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #544728; }

/* ---------- 3. 氛围层(静态、零动画、不参与交互) ---------- */
body::before {
  content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(1300px 620px at 12% -8%, rgba(var(--accent-rgb), .06), transparent 60%),
    radial-gradient(1000px 560px at 96% 2%, rgba(184, 132, 46, .045), transparent 58%),
    radial-gradient(1200px 760px at 50% 116%, rgba(var(--ok-rgb), .04), transparent 62%),
    var(--bg);
}
body::after {
  content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27180%27 height=%27180%27%3E%3Cfilter id=%27n%27%3E%3CfeTurbulence type=%27fractalNoise%27 baseFrequency=%270.82%27 numOctaves=%272%27 stitchTiles=%27stitch%27/%3E%3CfeColorMatrix type=%27saturate%27 values=%270%27/%3E%3C/filter%3E%3Crect width=%27100%25%27 height=%27100%25%27 filter=%27url(%23n)%27/%3E%3C/svg%3E");
}
.bg-aurora { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.bg-orb { position: absolute; border-radius: 50%; }
.bg-orb-1 { width: 620px; height: 420px; top: -6%; left: -4%; background: radial-gradient(circle, rgba(227, 180, 94, .10), transparent 68%); }
.bg-orb-2 { width: 560px; height: 400px; top: 2%; right: -6%; background: radial-gradient(circle, rgba(184, 132, 46, .08), transparent 66%); }
.bg-orb-3 { width: 680px; height: 460px; bottom: -12%; left: 34%; background: radial-gradient(circle, rgba(var(--ok-rgb), .05), transparent 66%); }
.bg-aurora::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 92% at 50% 6%, transparent 54%, rgba(4, 3, 2, .5) 100%);
}

/* ---------- 4. 外壳:全站一条顶栏 ---------- */
.app { display: flex; flex-direction: column; height: 100vh; position: relative; z-index: 1; }
/* 需求三十九·移动端适配:移动浏览器地址栏伸缩会吃掉 100vh 的一段,dvh 跟随可视高度 */
@supports (height: 100dvh) { .app { height: 100dvh; } }
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.content {
  flex: 1; overflow-y: auto; min-height: 0;
  padding: var(--pad-page) var(--sp-8) var(--sp-10);
  /* 27·3:大屏两侧留白过多。内容上限改用「自适应左右内边距」实现 ——
     比给每个子元素 max-width + margin:auto 可靠:子元素自己的 margin 简写(如 .page-head)
     会盖掉居中的 auto 边距,宽屏下内容就整体偏左了。 */
  padding-inline: max(var(--sp-8), calc((100% - var(--content-w)) / 2));
}
/* 沉浸工作台:外壳铺满,滚动交给面板内部 */
body.immersive .content { padding: 0; overflow: hidden; display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h); flex-shrink: 0;
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 var(--sp-6);
  background: rgba(9, 8, 6, .92);
  border-bottom: 1px solid var(--line);
  position: relative; z-index: 60;
}
.topbar::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(var(--accent-hi-rgb), .45) 18%, rgba(var(--accent-deep-rgb), .35) 50%, rgba(var(--accent-hi-rgb), .45) 82%, transparent);
}
.topbar-left { display: flex; align-items: center; gap: var(--sp-5); min-width: 0; flex: 1 1 auto; }
.topbar-right { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; }

.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; text-decoration: none; }
.brand:hover { text-decoration: none; }
.brand-logo {
  width: 34px; height: 34px; border-radius: var(--r-sm);
  background: linear-gradient(140deg, rgba(var(--accent-hi-rgb), .22), rgba(var(--accent-deep-rgb), .12));
  border: 1px solid var(--line-strong); color: var(--gold);
  display: flex; align-items: center; justify-content: center;
}
.brand-logo svg { width: 19px; height: 19px; stroke-width: 1.9; }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name {
  font-family: var(--display); font-size: var(--fs-xl); font-weight: 700; letter-spacing: .06em;
  background: var(--grad-gold); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; white-space: nowrap;
}
.brand-sub { font-size: 9px; letter-spacing: .28em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }

/* 主导航 */
.top-nav { display: flex; align-items: center; gap: 2px; min-width: 0; }
.top-link {
  position: relative; display: inline-flex; align-items: center; gap: var(--gap-xs);
  padding: 7px var(--sp-3); border-radius: var(--r-sm);
  border: 1px solid transparent; background: none; color: var(--ink-2);
  font-size: var(--fs-md); font-weight: 600; white-space: nowrap; cursor: pointer;
  transition: color .15s, background .15s, border-color .15s;
}
.top-link svg { width: 15px; height: 15px; opacity: .7; transition: opacity .15s, color .15s; }
.top-link:hover { color: var(--ink); background: var(--surface-hover); text-decoration: none; }
.top-link:hover svg { opacity: 1; }
.top-link.active { color: var(--ink); background: var(--sel-soft); border-color: var(--sel-soft-line); }
.top-link.active svg { opacity: 1; color: var(--gold); }
.top-link.active::before {
  content: ''; position: absolute; left: var(--sp-3); right: var(--sp-3); bottom: -1px;
  height: 2px; border-radius: var(--r-full); background: var(--gold);
}

/* 导航收纳:中屏隐藏文字,窄屏折叠为「更多」下拉(不再横向静默裁切) */
.nav-more { position: relative; display: none; }
.nav-more-btn {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 7px var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: none;
  color: var(--ink-2); font-size: var(--fs-md); font-weight: 600; cursor: pointer;
}
.nav-more-btn:hover { color: var(--ink); border-color: var(--line-strong); }
.nav-more-btn svg { width: 14px; height: 14px; }
.nav-more-btn.has-active { color: var(--gold-text); border-color: var(--line-strong); }

/* 上下文区:项目 / 分集层级替换主导航 */
.ctx { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; flex: 1 1 auto; }
.ctx-back {
  display: inline-flex; align-items: center; gap: var(--gap-xs); flex-shrink: 0;
  padding: 6px 10px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: none; color: var(--ink-2); font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
}
.ctx-back:hover { color: var(--gold-text); border-color: var(--line-strong); text-decoration: none; }
.ctx-back svg { width: 14px; height: 14px; }
.ctx-head { display: flex; flex-direction: column; min-width: 0; }
.ctx-eyebrow {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ctx-title {
  font-family: var(--display); font-size: var(--fs-xl); font-weight: 700; letter-spacing: .03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ctx-tabs {
  display: flex; gap: 3px; padding: 3px; border-radius: var(--r-sm); flex-shrink: 0;
  background: rgba(var(--film), .04); border: 1px solid var(--line);
}
.ctx-tab {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 6px var(--sp-3);
  border: none; border-radius: var(--r-xs); background: transparent; color: var(--ink-2);
  font-size: var(--fs-sm); font-weight: 700; cursor: pointer; white-space: nowrap; transition: all .15s;
}
.ctx-tab svg { width: 13px; height: 13px; opacity: .7; }
.ctx-tab:hover { color: var(--ink); }
.ctx-tab.active { background: var(--sel-fill); color: var(--sel-ink); border-color: var(--sel-line); }
.ctx-tab.active svg { opacity: 1; }
.ctx-spacer { flex: 1 1 auto; min-width: var(--sp-2); }

/* 顶栏右侧控件 */
.cmdk-trigger {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 0 10px; height: var(--h-md);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: rgba(var(--film), .03);
  color: var(--ink-2); font-size: var(--fs-sm); cursor: pointer; transition: all .15s;
}
.cmdk-trigger:hover { color: var(--ink); border-color: var(--line-strong); }
.cmdk-trigger svg { width: 14px; height: 14px; color: var(--gold); }
.cmdk-t-kbd { display: inline-flex; gap: 3px; }

.credit-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 0 11px; height: var(--h-md);
  border-radius: var(--r-full); border: 1px solid rgba(var(--ok-rgb), .35);
  background: rgba(var(--ok-rgb), .08); color: var(--ok); font-size: var(--fs-sm); font-weight: 700;
  cursor: pointer; transition: all .15s;
}
.credit-chip svg { width: 14px; height: 14px; }
.credit-chip b { font-family: var(--mono); font-size: var(--fs-md); }
.credit-chip:hover { border-color: var(--ok); background: rgba(var(--ok-rgb), .15); }

.icon-btn {
  width: var(--h-md); height: var(--h-md); padding: 0; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: rgba(var(--film), .03); color: var(--ink-2);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  position: relative; flex-shrink: 0; transition: all .15s;
}
.icon-btn svg { width: 16px; height: 16px; }
.icon-btn:hover { color: var(--ink); border-color: var(--line-strong); background: var(--surface-hover); }
.icon-btn:active { transform: scale(.95); }
.icon-btn.on, .icon-btn.active { color: var(--sel-soft-ink); border-color: var(--sel-soft-line); background: var(--sel-soft); }
.icon-btn:disabled { opacity: .4; cursor: not-allowed; }
.badge {
  position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--r-full); background: var(--danger); color: var(--danger-ink);
  font-size: 10px; font-weight: 800; display: flex; align-items: center; justify-content: center;
}

.top-user { position: relative; }
.top-user-btn {
  display: flex; align-items: center; gap: 8px; height: var(--h-md); padding: 0 9px 0 4px;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: rgba(var(--film), .03);
  color: var(--ink); font-size: var(--fs-sm); font-weight: 600; cursor: pointer; transition: all .15s;
}
.top-user-btn:hover { border-color: var(--line-strong); background: var(--surface-hover); }
.top-user-btn .tu-avatar { width: 26px; height: 26px; font-size: var(--fs-xs); }
.top-user-btn .tu-name { max-width: 92px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top-user-btn .tu-caret { color: var(--ink-3); display: inline-flex; }
.top-user-btn .tu-caret svg { width: 12px; height: 12px; }

.avatar {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, rgba(var(--accent-rgb), .28), rgba(var(--accent-deep-rgb), .2));
  border: 1px solid var(--line-strong); color: var(--gold-text);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: var(--fs-md);
}

/* ---------- 5. 弹层 ---------- */
.top-user-pop, .notif-panel, .menu-pop, .ctx-menu, .nav-more-pop {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 216px; padding: 6px; z-index: 120;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--elev-3); animation: popDown .18s cubic-bezier(.21, .9, .35, 1.1) both;
}
.menu { position: relative; }
.menu-pop { min-width: 180px; }
/* 需求三十九·续:抽屉按钮(nav-more)在窄屏贴着视口左缘,absolute + right:0 会把弹层
   整个推到视口外(390px 实测左缘 -91,菜单被屏幕边裁掉一半,用户看到的就是「被遮住」)。
   改 fixed 贴视口左上角下拉 —— 跟按钮在哪无关,任何宽度都不出屏。 */
.nav-more-pop {
  position: fixed; left: 10px; top: calc(var(--topbar-h) + 6px); right: auto;
  max-width: calc(100vw - 20px);
}
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px var(--sp-3);
  border: none; border-radius: var(--r-sm); background: none; color: var(--ink);
  font-size: var(--fs-sm); text-align: left; cursor: pointer; text-decoration: none; transition: background .13s;
}
.menu-item:hover { background: var(--surface-hover); text-decoration: none; }
.menu-item svg { width: 15px; height: 15px; color: var(--ink-2); }
.menu-item:hover svg { color: var(--gold); }
.menu-item.danger, .menu-item.danger svg { color: var(--danger); }
.menu-item.danger:hover { background: rgba(var(--danger-rgb), .1); }
.menu-item.active { color: var(--gold-text); }

.top-user-pop { width: 252px; }
.tu-pop-head { padding: var(--sp-3); border-bottom: 1px solid var(--line); margin-bottom: 5px; }
.tu-pop-name { font-weight: 700; font-size: var(--fs-md); }
.tu-pop-role { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; }
.tu-pop-storage { margin-top: var(--sp-3); }
.tu-pop-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px var(--sp-3);
  border: none; border-radius: var(--r-sm); background: none; color: var(--ink);
  font-size: var(--fs-sm); text-align: left; cursor: pointer; text-decoration: none; transition: background .13s;
}
.tu-pop-item:hover { background: var(--surface-hover); text-decoration: none; }
.tu-pop-item svg { width: 15px; height: 15px; color: var(--ink-2); }
.tu-pop-item:hover svg { color: var(--gold); }
.tu-pop-item.danger, .tu-pop-item.danger svg { color: var(--danger); }
.tu-pop-item.danger:hover { background: rgba(var(--danger-rgb), .1); }

.storage-label { display: flex; justify-content: space-between; font-size: var(--fs-xs); color: var(--ink-2); margin-bottom: 5px; }
.storage-bar { height: 5px; background: rgba(var(--film), .07); border-radius: var(--r-full); overflow: hidden; }
.storage-fill { height: 100%; background: var(--ok); border-radius: var(--r-full); transition: width .4s; }

.notif-panel { width: 340px; max-height: 440px; overflow-y: auto; }
.notif-item { padding: var(--sp-3); border-radius: var(--r-sm); cursor: pointer; transition: background .13s; }
.notif-item:hover { background: var(--surface-hover); }
.notif-item + .notif-item { margin-top: 2px; border-top: 1px solid var(--line); }
.notif-item .n-title { font-weight: 700; font-size: var(--fs-md); display: flex; align-items: center; gap: var(--gap-xs); }
.notif-item .n-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex-shrink: 0; }
.notif-item .n-body { font-size: var(--fs-sm); color: var(--ink-2); margin-top: 3px; }
.notif-item .n-time { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px; }
.notif-empty { padding: var(--sp-8); text-align: center; color: var(--ink-3); font-size: var(--fs-md); }


/* 图标 */
i.ico { display: inline-flex; flex-shrink: 0; }
svg.lucide { width: 16px; height: 16px; flex-shrink: 0; vertical-align: -3px; }
svg.ico-xs, i.ico.ico-xs svg { width: 12px; height: 12px; }
svg.ico-sm, i.ico.ico-sm svg { width: 14px; height: 14px; }

kbd.kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 19px; height: 19px;
  padding: 0 5px; font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--ink-2);
  background: rgba(var(--film), .05); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 5px;
}

/* ---------- 6. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--gap-xs);
  height: var(--h-md); padding: 0 var(--sp-4); border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink);
  font-size: var(--fs-md); font-weight: 600; cursor: pointer; white-space: nowrap;
  transition: border-color .15s, background .15s, color .15s, box-shadow .15s;
}
.btn svg { width: 15px; height: 15px; }
.btn:hover { border-color: var(--line-strong); background: var(--surface-3); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-primary { background: var(--gold-fill); border-color: transparent; color: var(--gold-ink); font-weight: 700; }
.btn-primary:hover { background: var(--gold-fill-h); border-color: transparent; }
.btn-primary:active { background: var(--gold-fill-a); }
.btn-danger { background: rgba(var(--danger-rgb), .1); border-color: rgba(var(--danger-rgb), .4); color: var(--danger); }
.btn-danger:hover { background: rgba(var(--danger-rgb), .18); border-color: rgba(var(--danger-rgb), .6); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-hover); color: var(--ink); border-color: transparent; }
.btn-sm { height: var(--h-sm); padding: 0 var(--sp-3); font-size: var(--fs-sm); }
.btn-sm svg { width: 13px; height: 13px; }
.btn-xs { height: var(--sq-sm); padding: 0 9px; font-size: var(--fs-xs); gap: var(--gap-xs); border-radius: var(--r-xs); }
.btn-xs svg { width: 12px; height: 12px; }
.btn-block { width: 100%; height: var(--h-lg); font-size: var(--fs-lg); }
.btn-link { border: none; background: none; padding: 0; color: var(--ok); cursor: pointer; font-size: var(--fs-sm); }
.btn-link:hover { text-decoration: underline; }
.btn-group { display: inline-flex; gap: var(--sp-2); align-items: center; }

/* ---------- 7. 表单 ---------- */
.input, .select, .textarea {
  width: 100%; min-height: var(--h-md); padding: 8px var(--sp-3);
  background: rgba(var(--film), .03); border: 1px solid var(--line); border-radius: var(--r-sm);
  color: var(--ink); font-size: var(--fs-md); font-family: var(--font); outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.input:focus, .select:focus, .textarea:focus { border-color: var(--gold); box-shadow: var(--ring); }
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.textarea { min-height: 88px; line-height: 1.7; resize: vertical; }
.select { cursor: pointer; }
.field { margin-bottom: var(--sp-4); }
.field > label {
  display: block; font-size: var(--fs-sm); color: var(--ink-2); margin-bottom: 6px;
  font-weight: 700; letter-spacing: .02em;
}
.field .hint, .hint { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 5px; line-height: 1.6; }
.field > .hint:first-of-type { margin-top: 6px; }
input[type="range"] { width: 100%; accent-color: var(--gold); cursor: pointer; }
input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--gold); cursor: pointer; }
.form-row { display: flex; gap: var(--sp-3); }
.form-row > * { flex: 1; min-width: 0; }
/* 长表单分段:让"模型 / 描述 / 规格"一眼可辨 */
.form-sect {
  margin: var(--sp-5) 0 var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--line);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.form-sect:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.search-box { position: relative; width: 280px; max-width: 100%; }
.search-box .input { padding-left: 34px; }
.search-box .search-ico {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--ink-3); display: inline-flex;
}
.search-box .search-ico svg { width: 14px; height: 14px; }

/* ---------- 8. 卡片与网格 ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--pad-card); margin-bottom: var(--sp-4); box-shadow: var(--elev-2);
  transition: border-color .18s, box-shadow .18s;
}
.card:hover { border-color: var(--line-strong); }
.card-title {
  font-size: var(--fs-lg); font-weight: 700; margin-bottom: var(--sp-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
}
.grid { display: grid; gap: var(--gap); }
.grid-cards { grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr)); }
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--gap-sm); margin-bottom: var(--sp-6); }
.stat-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--pad-card-sm); box-shadow: var(--card-shadow); transition: border-color .18s, box-shadow .18s;
}
.stat-card:hover { border-color: var(--line-strong); }
.stat-value { font-family: var(--mono); font-feature-settings: "tnum"; font-size: var(--fs-3xl); font-weight: 700; line-height: 1.1; letter-spacing: -.01em; }
.stat-value small { font-size: var(--fs-lg); color: var(--ink-2); margin-left: 3px; }
.stat-label { font-size: var(--fs-sm); color: var(--ink-2); margin-top: 4px; }

/* ---------- 9. 媒体卡 ---------- */
.media-card {
  position: relative; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); overflow: hidden; cursor: pointer; box-shadow: var(--card-shadow); transition: border-color .18s, box-shadow .18s, transform .18s;
}
.media-card:hover { border-color: var(--line-strong); transform: translateY(-2px); box-shadow: var(--elev-2); }
.media-card.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
.media-thumb { width: 100%; aspect-ratio: 16 / 10; background: var(--surface-2); object-fit: cover; }
.media-thumb-empty { display: flex; align-items: center; justify-content: center; color: var(--ink-3); }
.media-thumb-empty svg { width: 30px; height: 30px; opacity: .5; }
.media-type-badge {
  position: absolute; top: var(--sp-2); left: var(--sp-2); display: inline-flex; align-items: center;
  padding: 3px 8px; border-radius: var(--r-xs); font-size: var(--fs-xs); font-weight: 700;
  background: rgba(var(--scrim-rgb), .72); color: var(--scrim-ink); border: 1px solid var(--scrim-line);
}
.media-type-badge svg { width: 12px; height: 12px; }
.media-actions { position: absolute; top: var(--sp-2); right: 42px; display: none; gap: var(--gap-xs); }
.media-card:hover .media-actions { display: flex; }
.media-actions .icon-btn {
  width: 28px; height: 28px; border-radius: var(--r-sm); background: rgba(var(--scrim-rgb), .78);
  border-color: var(--scrim-line); color: var(--scrim-ink);
}
.media-actions .icon-btn svg { width: 13px; height: 13px; }
.media-body { padding: 10px var(--sp-3) var(--sp-3); }
.media-name { font-size: var(--fs-md); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.media-meta {
  font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.media-cat { margin-top: 6px; display: flex; align-items: center; min-height: 20px; }
.asset-check {
  position: absolute; top: var(--sp-2); right: var(--sp-2); z-index: 3;
  width: 24px; height: 24px; border-radius: var(--r-sm);
  border: 1.5px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .7); color: transparent;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transform: scale(.9); transition: all .15s;
}
.media-card:hover .asset-check, .selecting .asset-check, .proj-card:hover .asset-check, .card:hover .asset-check { opacity: 1; transform: none; }
.asset-check.on { opacity: 1; transform: none; background: var(--gold); border-color: var(--gold); color: var(--gold-ink); }
/* 勾在卡片表面(不是压在缩略图上)的两处:用表面薄雾 + 实描边。
   深底浮层那套放在白卡上既不合语境,深色下又几乎看不见。 */
.style-check, .proj-check { background: rgba(var(--film), .07); border-color: var(--line-strong); }
.style-check.on, .proj-check.on { background: var(--gold); border-color: var(--gold); }

/* 分类 chips */
.cat-chips { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.cat-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-sm); padding: 0 var(--sp-3);
  border-radius: var(--r-full); border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink-2); font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
  white-space: nowrap; transition: all .15s;
}
.cat-chip svg { width: 13px; height: 13px; }
.cat-chip:hover { color: var(--ink); border-color: var(--line-strong); }
.cat-chip.on { background: var(--sel-fill); border-color: var(--sel-line); color: var(--sel-ink); }
.cat-chip.on svg { color: var(--sel-ink); }
.cat-chip .chip-n { color: var(--ink-3); font-weight: 700; font-variant-numeric: tabular-nums; }
.cat-chip.on .chip-n { color: inherit; opacity: .72; }

/* ---------- 分页控件(26·1:资源/素材类列表每页 20 条) ----------
   吸附在滚动区底部:20 张卡约 1700px 高,分页条排在列表末尾时,用户第一眼会以为「没有分页」(26·6) */
.pager {
  position: sticky; bottom: var(--sp-2); z-index: 6;
  display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap;
  margin: var(--sp-4) 0 var(--sp-2); padding: var(--sp-2) var(--sp-3);
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--elev-2);
}
.pager:empty { display: none; }
/* 资产库 / 生图记录的页脚:分页条挪出滚动区,永远占自己那一行,不再压住卡片 */
.ast-pager, .ig-res-foot {
  position: static; flex-shrink: 0; margin: 0; box-shadow: none;
  border: 0; border-top: 1px solid var(--line); border-radius: 0;
  background: var(--surface); padding: var(--sp-2) var(--sp-3);
}
body:not(.page-fill) .ast-pager { border: 1px solid var(--line-strong); border-radius: var(--r-md); box-shadow: var(--elev-2); margin: var(--sp-4) 0 var(--sp-2); }
.pager-info { font-size: var(--fs-sm); color: var(--ink-3); margin-right: var(--sp-2); }
.pager-info b { font-family: var(--mono); }
.pg-btn {
  display: inline-flex; align-items: center; gap: var(--gap-xs); min-width: var(--h-sm); height: var(--h-xs); padding: 0 9px;
  border-radius: var(--r-full); border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink-2); font-size: var(--fs-sm); font-weight: 600; cursor: pointer; transition: all .14s;
}
.pg-btn svg { width: 13px; height: 13px; }
.pg-btn:hover { color: var(--ink); border-color: var(--line-strong); background: var(--surface-hover); }
.pg-btn.on { background: var(--sel-fill); border-color: var(--sel-line); color: var(--sel-ink); }
.pg-btn:disabled { opacity: .38; cursor: default; background: var(--surface-2); color: var(--ink-3); border-color: var(--line); }
.pg-gap { color: var(--ink-3); padding: 0 2px; }

.ig-count { font-size: var(--fs-xs); color: var(--ink-3); font-family: var(--mono); font-weight: 400; }
.ig-neg { margin-top: 0; min-height: 62px; resize: vertical; font-size: var(--fs-sm); }
/* 低频参数(质量 / 种子)折叠,保证一屏放得下 */
.ig-more { margin: 2px 0 var(--sp-2); }
.ig-more > summary {
  display: flex; align-items: center; gap: var(--gap-xs); cursor: pointer; list-style: none;
  font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); padding: 5px 0;
}
.ig-more > summary::-webkit-details-marker { display: none; }
.ig-more > summary:hover { color: var(--gold-text); }
.ig-more[open] > summary { color: var(--gold-text); }
/* 输出规格读数(26·3:比例 × 分辨率 → 具体尺寸,选完就看到) */
.ig-spec-out { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin: 2px 0 var(--sp-3); color: var(--ink-2); }
/* 后台:生图规则模板一键填入 */
.em-tpl-row { display: flex; gap: var(--gap-xs); flex-wrap: wrap; margin-top: 6px; }
.ig-spec-out svg { width: 13px; height: 13px; color: var(--gold); }
.ig-spec-out b { font-family: var(--mono); color: var(--gold-text); }
.ig-spec-note { color: var(--ink-3); }
.dash-more { font-size: var(--fs-sm); color: var(--ink-3); padding-top: var(--sp-2); }
.dash-more svg { width: 12px; height: 12px; vertical-align: -2px; }

/* ---------- 10. 标签 / 状态 / 进度 ---------- */
.tag {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700; padding: 2px var(--sp-2); border-radius: var(--r-full);
  background: rgba(var(--ok-rgb), .12); color: var(--ok); border: 1px solid rgba(var(--ok-rgb), .28);
}
.tag-cat {
  display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700; padding: 2px var(--sp-2);
  border-radius: var(--r-full); background: rgba(var(--accent-rgb), .12);
  border: 1px solid var(--line-strong); color: var(--gold-text);
}
.tag-cat svg { width: 11px; height: 11px; }
.tag-cat-none { background: rgba(var(--film), .04); border-color: var(--line); color: var(--ink-3); }

.status {
  display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700;
  padding: 2px var(--sp-2); border-radius: var(--r-full); white-space: nowrap;
}
.status-queued { background: rgba(var(--film), .06); color: var(--ink-2); }
.status-processing { background: var(--proc-soft); color: var(--proc-text); }
.status-completed { background: rgba(var(--ok-rgb), .14); color: var(--ok); }
.status-failed { background: rgba(var(--danger-rgb), .12); color: var(--danger); }
.status-cancelled { background: rgba(var(--film), .05); color: var(--ink-2); }
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: pulse 1.2s infinite; }

.progress { height: 5px; background: rgba(var(--film), .07); border-radius: var(--r-full); overflow: hidden; margin-top: 6px; }
.progress-fill { height: 100%; background: var(--gold-fill); border-radius: var(--r-full); transition: width .4s; }

/* ---------- 11. 表格 ---------- */
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); }
.table th {
  text-align: left; padding: var(--head-py) var(--sp-4); color: var(--ink-2); font-size: var(--fs-sm);
  font-weight: 700; border-bottom: 1px solid var(--line-strong); white-space: nowrap;
}
.table td { padding: var(--row-py) var(--sp-4); border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover td { background: var(--surface-hover); }
.table .td-empty { text-align: center; padding: var(--sp-8) var(--sp-4); color: var(--ink-3); font-size: var(--fs-md); }
.table-more { display: flex; justify-content: center; padding: var(--sp-3); border-top: 1px solid var(--line); }
.muted { color: var(--ink-3); font-size: var(--fs-sm); }
.num { font-family: var(--mono); }

/* 行数裁切工具:卡片 / 表格里的说明性文本必须定行,否则同一行里的元素高度各走各的 */
.clamp-1, .clamp-2 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.clamp-1 { -webkit-line-clamp: 1; }
.clamp-2 { -webkit-line-clamp: 2; }

/* ---------- 12. 空态 / 加载 ---------- */
.empty { text-align: center; padding: var(--sp-10) var(--sp-5); color: var(--ink-3); }
.empty-ico { margin-bottom: var(--sp-3); opacity: .55; color: var(--ink-3); display: inline-flex; }
.empty-ico svg { width: 40px; height: 40px; }
.empty h3 { color: var(--ink-2); font-size: var(--fs-lg); margin-bottom: 5px; }
.empty p { font-size: var(--fs-sm); line-height: 1.7; }
.spinner {
  width: 22px; height: 22px; border-radius: 50%; display: inline-block;
  border: 2px solid rgba(var(--film), .12); border-top-color: var(--gold);
  animation: spin .7s linear infinite;
}
.spinner-sm { width: 14px; height: 14px; border-width: 2px; vertical-align: -2px; }
.loading-wrap { display: flex; justify-content: center; padding: var(--sp-10); }

/* ---------- 13. 弹窗 / Toast / 右键菜单 / ⌘K ---------- */
.modal-mask {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
  padding: var(--sp-4); background: rgba(4, 3, 2, .72); backdrop-filter: blur(6px);
  animation: maskIn .18s ease both;
}
.modal {
  display: flex; flex-direction: column; width: 560px; max-width: 96vw; max-height: 88vh;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--elev-3); animation: modalIn .26s cubic-bezier(.21, 1.02, .55, 1) both;
}
/* 需求三十九:手机键盘弹起 / 地址栏收展时 88vh 不再够用,dvh 跟随真实可视高 */
@supports (height: 100dvh) { .modal { max-height: 88dvh; } }
.modal-sm { width: 420px; }
.modal-md { width: 680px; }
.modal-lg { width: 900px; }
.modal-xl { width: 1140px; }
.modal-head {
  flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line);
}
.modal-title { font-size: var(--fs-lg); font-weight: 700; display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.modal-title svg { color: var(--gold); flex-shrink: 0; }
.modal-x { width: var(--sq-md); height: var(--sq-md); border-radius: var(--r-sm); }
.modal-x svg { width: 15px; height: 15px; }
.modal-body { padding: var(--sp-5); overflow-y: auto; flex: 1; min-height: 0; }
.modal-foot {
  flex-shrink: 0; display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line); flex-wrap: wrap;
}
.modal-foot .btn { min-width: 84px; }
.modal-foot .btn-primary { min-width: 104px; }

/* 提示条钉在顶部居中:原来挂在右上角,正好压在「生图模型」下拉上 —— 刚选完参考图要接着
   看模型,提示条却把控件盖住三秒。顶栏下面那一带整站都是静态标题,压一会儿没有代价。
   根节点不吃鼠标(pointer-events:none),空白区不会挡住下面的按钮。 */
#toastRoot { position: fixed; top: calc(var(--topbar-h) + 12px); left: 50%; transform: translateX(-50%);
  z-index: 300; display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); pointer-events: none; }
.toast {
  position: relative; overflow: hidden; display: flex; align-items: flex-start; gap: 10px;
  max-width: min(360px, calc(100vw - 32px)); padding: 11px var(--sp-4); border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line-strong); border-left: 3px solid var(--gold);
  box-shadow: var(--elev-3); font-size: var(--fs-md); pointer-events: auto;
  animation: toastInC .28s cubic-bezier(.21, 1.02, .55, 1) both;
}
.toast.ok { border-left-color: var(--ok); }
.toast.err { border-left-color: var(--danger); }
.toast .toast-ico { margin-top: 2px; }
.toast .toast-ico svg { width: 15px; height: 15px; color: var(--gold); }
.toast.ok .toast-ico svg { color: var(--ok); }
.toast.err .toast-ico svg { color: var(--danger); }
.toast::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: linear-gradient(90deg, rgba(var(--accent-rgb), .8), rgba(var(--accent-rgb), .1));
  animation: toastLife 3.2s linear forwards;
}
.toast.ok::after { background: linear-gradient(90deg, rgba(var(--ok-rgb), .8), rgba(var(--ok-rgb), .1)); }
.toast.err::after { background: linear-gradient(90deg, rgba(var(--danger-rgb), .8), rgba(var(--danger-rgb), .1)); }

.ctx-menu { position: fixed; z-index: 400; min-width: 178px; }
.ctx-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px var(--sp-3);
  border: none; border-radius: var(--r-sm); background: none; color: var(--ink);
  font-size: var(--fs-sm); text-align: left; cursor: pointer; transition: background .13s;
}
.ctx-item:hover { background: var(--surface-hover); }
.ctx-item svg { width: 14px; height: 14px; color: var(--ink-2); }
.ctx-item:hover svg { color: var(--gold); }
.ctx-item .ctx-ico-ph { width: 14px; flex-shrink: 0; }
.ctx-item.danger, .ctx-item.danger svg { color: var(--danger); }
.ctx-item.danger:hover { background: rgba(var(--danger-rgb), .1); }
.ctx-item.disabled { opacity: .4; pointer-events: none; }
.ctx-sep { height: 1px; margin: 5px var(--sp-2); background: var(--line); }

.cmdk-mask {
  position: fixed; inset: 0; z-index: 500; display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh var(--sp-4) 0; background: rgba(4, 3, 2, .72); backdrop-filter: blur(6px);
  animation: maskIn .18s ease both;
}
.cmdk {
  position: relative; overflow: hidden; width: 620px; max-width: 96vw;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  box-shadow: var(--elev-3); animation: modalIn .24s cubic-bezier(.21, 1.02, .55, 1) both;
}
.cmdk-input-row { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line); }
.cmdk-input-row > svg { width: 16px; height: 16px; color: var(--gold); flex-shrink: 0; }
.cmdk-input { flex: 1; background: none; border: none; outline: none; color: var(--ink); font-size: var(--fs-lg); font-family: var(--font); }
.cmdk-input::placeholder { color: var(--ink-3); }
.cmdk-list { max-height: 46vh; overflow-y: auto; padding: 6px; overscroll-behavior: contain; }
@supports (height: 100dvh) { .cmdk-list { max-height: 46dvh; } }
.cmdk-group-label { padding: 10px var(--sp-3) 5px; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.cmdk-item {
  display: flex; align-items: center; gap: var(--sp-3); padding: 9px var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid transparent; cursor: pointer; user-select: none;
  color: var(--ink-2); font-size: var(--fs-md);
}
.cmdk-item > svg { width: 15px; height: 15px; color: var(--ink-3); flex-shrink: 0; }
.cmdk-item.sel { background: var(--sel-soft); border-color: var(--sel-soft-line); color: var(--ink); }
.cmdk-item.sel > svg { color: var(--gold); }
.cmdk-item .ci-sub { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 1px; }
.cmdk-item .ci-go { margin-left: auto; opacity: 0; display: inline-flex; }
.cmdk-item .ci-go svg { width: 13px; height: 13px; }
.cmdk-item.sel .ci-go { opacity: 1; }
.cmdk-empty { padding: var(--sp-10) var(--sp-5); text-align: center; color: var(--ink-3); font-size: var(--fs-md); }
.cmdk-foot {
  display: flex; align-items: center; gap: var(--sp-4); padding: 10px var(--sp-5);
  border-top: 1px solid var(--line); background: rgba(0, 0, 0, .18);
  font-size: var(--fs-xs); color: var(--ink-3);
}
.cmdk-foot span { display: inline-flex; align-items: center; gap: var(--gap-xs); }
.cmdk-mark {
  margin-left: auto; font-family: var(--display); font-size: var(--fs-xs); letter-spacing: .08em;
  background: var(--grad-gold); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

/* ---------- 14. 登录 / 注册 ---------- */
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: var(--sp-5); position: relative; z-index: 1; }
@supports (height: 100dvh) { .auth-wrap { min-height: 100dvh; } }
/* 需求三十九:触屏基础 —— 点按去灰块、交互元素去双击缩放延迟(现代浏览器配 viewport 后本就没有 300ms,这里是兜底) */
html { -webkit-tap-highlight-color: transparent; }
button, a, input, select, textarea, label, summary { touch-action: manipulation; }
.auth-stage {
  display: flex; width: 100%; max-width: 980px; overflow: hidden; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--line-strong); box-shadow: var(--elev-3);
  animation: fadeUp .5s cubic-bezier(.21, 1.02, .47, 1) both;
}
.auth-poster {
  position: relative; flex: 1.05; min-width: 0; display: flex; flex-direction: column;
  padding: var(--sp-10) var(--sp-8) var(--sp-10);
  background:
    radial-gradient(130% 90% at 18% -4%, rgba(var(--accent-rgb), .14), transparent 58%),
    linear-gradient(205deg, #15120d, #0a0908);
}
.ap-kicker { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .32em; text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--sp-6); }
.ap-title {
  font-family: var(--display); font-size: var(--fs-3xl); font-weight: 700; line-height: 1.35; letter-spacing: .05em;
  background: var(--grad-gold); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.ap-sub { margin-top: var(--sp-4); font-size: var(--fs-md); color: var(--ink-2); }
.ap-foot { margin-top: auto; padding-top: var(--sp-8); font-size: var(--fs-sm); color: var(--ink-3); line-height: 1.9; }
.ap-foot b { color: var(--ink-2); font-family: var(--mono); font-weight: 600; }
.auth-card { width: 420px; flex-shrink: 0; padding: var(--sp-10) var(--sp-8); border-left: 1px solid var(--line); }
.auth-logo { margin-bottom: 10px; color: var(--gold); display: flex; }
.auth-logo svg { width: 34px; height: 34px; }
.auth-title { font-family: var(--display); font-size: var(--fs-2xl); font-weight: 700; letter-spacing: .06em; background: var(--grad-gold); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.auth-sub { color: var(--ink-2); font-size: var(--fs-sm); margin: 4px 0 var(--sp-6); }
.auth-switch { text-align: center; margin-top: var(--sp-5); font-size: var(--fs-sm); color: var(--ink-2); }

/* ---------- 15. 页面头与通用布局 ---------- */
/* 27·1:页头压成一行(眉标 + 标题 + 说明同行,说明超长省略),把竖向空间让给操作区 */
.page-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  flex-wrap: wrap; margin: 0 0 var(--sp-3); flex-shrink: 0;
  /* 页头里的下拉面板要永远压在内容栏(卡片网格 / 滚动面板)之上 */
  position: relative; z-index: 30;
}
.page-head-main { display: flex; align-items: baseline; gap: var(--sp-3); min-width: 0; flex: 1 1 320px; }
.page-eyebrow {
  display: inline-flex; align-items: center; gap: var(--gap-xs); flex-shrink: 0;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3);
}
.page-eyebrow svg { color: var(--gold); width: 13px; height: 13px; }
.page-title { font-family: var(--display); font-size: var(--fs-page-title); font-weight: 700; letter-spacing: .03em; white-space: nowrap; }
.page-sub {
  font-size: var(--fs-xs); color: var(--ink-3); min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.page-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; flex-shrink: 0; }

/* 筛选行:只放过滤控件;动作按钮归入 page-head */
.filters { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-3); flex-shrink: 0; }
.filters .grow { flex: 1 1 auto; }
.filters-divider { width: 1px; height: 22px; background: var(--line); margin: 0 var(--sp-1); }

/* ---------- 27·2:填充式页面(资产库 / AI 生图)----------
   顶栏与页头、筛选行固定不动,只有内容栏各自滚动 ——
   替代上一轮「整页滚动 + 侧栏 sticky」的做法:侧栏不再需要跟着滚,滚动条也只有一根。 */
body.page-fill .content { overflow: hidden; display: flex; flex-direction: column; padding-bottom: var(--sp-4); }
body.page-fill .page-head, body.page-fill .filters, body.page-fill .cat-chips { flex-shrink: 0; }
body.page-fill .cat-chips { margin-bottom: var(--sp-3); }
/* 资产库:左=文件夹,右=网格(各自可滚),分页条吸附在网格栏底部 */
body.page-fill .ast-layout { flex: 1 1 auto; min-height: 0; align-items: stretch; }
body.page-fill .ast-side { position: static; min-height: 0; overflow-y: auto; }
body.page-fill .ast-main { min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
body.page-fill .ast-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 5px; }
/* 窄屏与矮屏退回整页滚动:两栏堆叠时内部滚动会把内容压成一条缝 */
@media (max-width: 1080px) {
  body.page-fill .content { overflow-y: auto; display: block; padding-bottom: var(--sp-10); }
  body.page-fill .ast-layout, body.page-fill .dw, body.page-fill .dw-ws { flex: none; align-items: start; }
  body.page-fill .ast-side, body.page-fill .ast-main, body.page-fill .ast-scroll,
  body.page-fill .dw-rail, body.page-fill .dw-main,
  body.page-fill .dw-eps-list, body.page-fill .dw-shots { overflow: visible; min-height: 0; max-height: none; padding-right: 0; }
  body.page-fill .ast-side { position: sticky; top: var(--sp-4); }
}
@media (max-height: 620px) {
  body.page-fill .content { overflow-y: auto; display: block; }
  body.page-fill .ast-layout { flex: none; align-items: start; }
  body.page-fill .ast-main, body.page-fill .ast-scroll,
  body.page-fill .dw-rail, body.page-fill .dw-main, body.page-fill .dw-shots { overflow: visible; min-height: 0; }
}

/* 工具条(兼容既有结构,视觉等同 filters) */
.toolbar { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.toolbar .grow { flex: 1 1 auto; }

/* 面包屑 */

/* 标签页 */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: var(--sp-5); flex-wrap: wrap; }
.tab {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 9px var(--sp-4);
  font-size: var(--fs-md); font-weight: 600; color: var(--ink-2); cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px; transition: all .15s;
}
.tab svg { width: 14px; height: 14px; opacity: .7; }
.tab:hover { color: var(--ink); }
.tab.active { color: var(--gold-text); border-bottom-color: var(--gold); }
.tab.active svg { opacity: 1; }

/* 区块标题 */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin: var(--sp-6) 0 var(--sp-4); }
.section-title { font-size: var(--fs-lg); font-weight: 700; display: flex; align-items: center; gap: var(--sp-2); }
.section-title::before { content: ''; width: 3px; height: 15px; border-radius: var(--r-full); background: var(--gold); }
.section-more { font-size: var(--fs-sm); color: var(--ink-2); display: inline-flex; align-items: center; gap: var(--gap-xs); transition: color .15s, gap .15s; }
.section-more:hover { color: var(--gold-text); text-decoration: none; gap: var(--gap-xs); }

/* 上传拖放区 */
.dropzone {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-md); padding: var(--sp-8) var(--sp-5);
  text-align: center; color: var(--ink-2); cursor: pointer; background: rgba(var(--film), .02); transition: all .18s;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--gold); border-style: solid; color: var(--ink); background: var(--surface-hover); }
.dropzone .dz-ico { margin-bottom: var(--sp-2); color: var(--gold); display: inline-flex; }
.dropzone .dz-ico svg { width: 28px; height: 28px; stroke-width: 1.6; }

/* 浮条(批量操作) */
.ast-batchbar, .wb-batchbar {
  position: fixed; left: 50%; bottom: var(--sp-6); transform: translateX(-50%); z-index: 90;
  display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3) var(--sp-2) var(--sp-5);
  border-radius: var(--r-lg); font-size: var(--fs-md);
  background: var(--surface-2); border: 1px solid var(--line-strong); box-shadow: var(--elev-3);
  animation: barUp .26s cubic-bezier(.21, 1.02, .55, 1) both;
}
.ast-batchbar b, .wb-batchbar b { color: var(--gold-text); font-family: var(--mono); }

/* 返回顶部 */
.to-top {
  position: fixed; right: var(--sp-6); bottom: var(--sp-6); z-index: 150;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line-strong); background: var(--surface-2); color: var(--gold);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transform: translateY(10px); transition: all .2s ease;
  box-shadow: var(--elev-2);
}
.to-top.show { opacity: 1; pointer-events: auto; transform: none; }
.to-top:hover { border-color: var(--gold); background: var(--surface-3); }
.to-top svg { width: 16px; height: 16px; }

/* ---------- 16. 首页 ---------- */
.dash-hero {
  position: relative; overflow: hidden; display: flex; align-items: center; gap: var(--sp-5);
  padding: var(--sp-6) var(--sp-8); margin-bottom: var(--sp-6); border-radius: var(--r-md);
  /* background: linear-gradient(120deg, rgba(44, 34, 20, .7), var(--surface) 60%); */
  border: 1px solid var(--line-strong); box-shadow: var(--elev-2);
}
.dash-hero .dh-avatar {
  width: 52px; height: 52px; border-radius: var(--r-md); flex-shrink: 0;
  background: linear-gradient(135deg, rgba(var(--accent-rgb), .32), rgba(var(--accent-deep-rgb), .2));
  border: 1px solid var(--line-strong); color: var(--gold-text);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-2xl); font-weight: 700;
}
.dash-hero .dh-main { flex: 1; min-width: 0; }
.dash-hero .dh-title { font-family: var(--display); font-size: var(--fs-2xl); font-weight: 700; letter-spacing: .04em; }
.dash-hero .dh-sub { font-size: var(--fs-sm); color: var(--ink-2); margin-top: 4px; }
.dash-hero .dh-actions { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; flex-wrap: wrap; }
.dash-hero .dh-storage { width: 220px; flex-shrink: 0; }
.dash-hero .credit-inline { font-family: var(--mono); color: var(--ok); font-weight: 700; }

.stat-card.is-clickable { cursor: pointer; }
.stat-card.is-clickable:hover { border-color: var(--line-strong); }
.stat-hint { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px; }

/* 最近成果 */
.dash-recent { display: flex; gap: var(--sp-3); overflow-x: auto; padding-bottom: var(--sp-2); margin-bottom: var(--sp-5); scrollbar-width: thin; }
.dash-rec-tile {
  position: relative; flex: 0 0 200px; aspect-ratio: 16 / 10; padding: 0;
  border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--line);
  background: var(--surface-2); cursor: zoom-in;
}
.dash-rec-tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .2s ease; }
.dash-rec-tile:hover { border-color: var(--line-strong); }
.dash-rec-tile:hover img { transform: scale(1.04); }
.dash-rec-badge {
  position: absolute; left: var(--sp-2); top: var(--sp-2); display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-xs); padding: 2px 7px; border-radius: var(--r-xs); pointer-events: none;
  color: var(--scrim-ink); background: rgba(var(--scrim-rgb), .72); border: 1px solid var(--scrim-line);
}
.dash-rec-badge .ico { width: 11px; height: 11px; }
.dash-rec-empty { font-size: var(--fs-sm); color: var(--ink-3); padding: var(--sp-3) 2px; }

/* 项目卡 */
.dash-proj-card, .proj-card {
  position: relative; display: flex; flex-direction: column; gap: var(--sp-2); min-height: 158px;
  padding: var(--sp-4); border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--elev-2);
  color: var(--ink); text-decoration: none; transition: border-color .18s, transform .18s, box-shadow .18s;
}
.dash-proj-card:hover, .proj-card:hover { transform: translateY(-2px); border-color: var(--line-strong); text-decoration: none; box-shadow: var(--elev-3); }
.dash-proj-card.sel, .proj-card.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
.dash-proj-card .dp-row { display: flex; align-items: center; gap: var(--sp-2); }
.dash-proj-card .dp-ico { color: var(--gold); display: inline-flex; }
.dash-proj-card .dp-ico svg { width: 21px; height: 21px; }
.dash-proj-card .dp-name { font-family: var(--display); font-size: var(--fs-lg); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-proj-card .dp-desc {
  font-size: var(--fs-sm); color: var(--ink-3); line-height: 1.65;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.dash-proj-card .dp-foot { margin-top: auto; font-size: var(--fs-xs); color: var(--ink-3); display: flex; gap: var(--sp-3); }
.dash-proj-card .dp-foot b { color: var(--gold-text); font-weight: 700; font-family: var(--mono); }
.dash-new-card {
  min-height: 158px; border-radius: var(--r-md); border: 1.5px dashed var(--line-strong);
  background: rgba(var(--film), .015); color: var(--ink-2);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2);
  cursor: pointer; font-size: var(--fs-md); font-weight: 600; transition: all .18s;
}
.dash-new-card:hover { border-color: var(--gold); color: var(--gold-text); background: var(--surface-hover); }
.dash-new-card .dn-plus { display: inline-flex; }
.dash-new-card .dn-plus svg { width: 22px; height: 22px; stroke-width: 1.6; }

.proj-card-ico {
  width: 38px; height: 38px; border-radius: var(--r-sm); flex-shrink: 0;
  background: var(--surface-hover); border: 1px solid var(--line-strong); color: var(--gold);
  display: flex; align-items: center; justify-content: center;
}
.proj-card-ico svg { width: 20px; height: 20px; }
.proj-ops { position: absolute; top: 10px; right: 10px; display: flex; gap: var(--gap-xs); opacity: 0; transition: opacity .15s; z-index: 2; }
.proj-card:hover .proj-ops { opacity: 1; }
.proj-edit-btn, .proj-del-btn {
  width: 28px; height: 28px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all .13s;
}
.proj-edit-btn svg, .proj-del-btn svg { width: 13px; height: 13px; }
.proj-edit-btn:hover { color: var(--gold); border-color: var(--gold); }
.proj-del-btn:hover { color: var(--danger); border-color: var(--danger); }
.proj-check, .style-check { position: relative; top: auto; right: auto; display: inline-flex; margin: 0; opacity: .7; transform: none; flex-shrink: 0; }
.proj-card.sel .proj-check, .proj-check.on, .style-check.on, .card.sel .style-check { opacity: 1; }
.card.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }

.proj-code-badge {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 2px 9px; border-radius: var(--r-xs);
  border: 1px dashed var(--line-strong); background: var(--surface-hover); color: var(--gold-text);
  font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .1em; cursor: pointer;
}
.proj-code-badge svg { width: 11px; height: 11px; }
.member-tag {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 2px 9px; border-radius: var(--r-xs);
  font-size: var(--fs-xs); font-weight: 700; background: rgba(var(--ok-rgb), .12);
  border: 1px solid rgba(var(--ok-rgb), .35); color: var(--ok);
}

/* ---------- 18. 分集工作台(项目详情 · wb-*) ---------- */
.wb { height: 100%; display: flex; flex-direction: column; min-height: 0; }
.wb-toolbar {
  flex-shrink: 0; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-6); border-bottom: 1px solid var(--line); background: var(--surface);
}
.wb-tbtn {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-sm); padding: 0 var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: none; color: var(--ink-2);
  font-size: var(--fs-sm); font-weight: 600; cursor: pointer; white-space: nowrap; transition: all .15s;
}
.wb-tbtn svg { width: 13px; height: 13px; }
.wb-tbtn:hover { color: var(--ink); border-color: var(--line-strong); }
.wb-tbtn.active { color: var(--sel-soft-ink); border-color: var(--sel-soft-line); background: var(--sel-soft); }
.wb-search { position: relative; flex: 0 1 260px; min-width: 150px; }
.wb-search .search-ico { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--ink-3); display: inline-flex; }
.wb-search .search-ico svg { width: 13px; height: 13px; }
.wb-search input {
  width: 100%; height: var(--h-sm); padding: 0 var(--sp-3) 0 32px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: rgba(var(--film), .03); color: var(--ink);
  font-size: var(--fs-sm); outline: none; transition: border-color .15s, box-shadow .15s;
}
.wb-search input:focus { border-color: var(--gold); box-shadow: var(--ring); }
.wb-search input::placeholder { color: var(--ink-3); }

.wb-canvas { flex: 1; overflow-y: auto; min-height: 0; padding: var(--sp-5) var(--sp-6) var(--sp-6); }
.wb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-4); align-items: stretch; max-width: var(--content-w); margin: 0 auto; }
.wb-card {
  position: relative; display: flex; flex-direction: column; gap: var(--sp-2); min-height: 196px;
  padding: var(--sp-4); border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--elev-2);
  color: var(--ink); text-decoration: none; cursor: pointer; transition: border-color .18s, transform .18s, box-shadow .18s;
}
.wb-card:hover { transform: translateY(-2px); border-color: var(--line-strong); text-decoration: none; box-shadow: var(--elev-3); }
.wb-card.hide { display: none; }
.wb-card.dim { opacity: .5; }
.wb-ic {
  width: 38px; height: 38px; border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center;
  background: var(--surface-hover); border: 1px solid var(--line-strong); color: var(--gold);
}
.wb-ic svg { width: 19px; height: 19px; }
.wb-card-title { font-size: var(--fs-lg); font-weight: 700; }
.wb-card-sub { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.6; }
.wb-card-foot { margin-top: auto; font-size: var(--fs-xs); color: var(--ink-3); display: flex; align-items: center; gap: var(--sp-2); }
.wb-card-foot b { color: var(--gold-text); font-weight: 700; font-family: var(--mono); }
.wb-go { position: absolute; top: var(--sp-4); right: var(--sp-4); color: var(--gold); opacity: .55; display: inline-flex; transition: transform .16s, opacity .16s; }
.wb-go svg { width: 15px; height: 15px; }
.wb-card:hover .wb-go { transform: translateX(3px); opacity: 1; }

.wb-assets { border-color: rgba(var(--ok-rgb), .3); }
.wb-assets .wb-ic { background: rgba(var(--ok-rgb), .1); border-color: rgba(var(--ok-rgb), .35); color: var(--ok); }
.wb-assets:hover { border-color: rgba(var(--ok-rgb), .6); }
.wb-assets .wb-card-foot b { color: var(--ok); }
.wb-assets-strip { display: flex; gap: var(--gap-xs); }
.wb-assets-strip img { width: 34px; height: 34px; border-radius: var(--r-sm); object-fit: cover; border: 1px solid var(--line); background: var(--surface-2); }
.wb-assets-strip .wb-assets-more {
  width: 34px; height: 34px; border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs); font-weight: 700; color: var(--ok); background: rgba(var(--ok-rgb), .1); border: 1px dashed rgba(var(--ok-rgb), .4);
}


.wb-ep-num {
  display: inline-flex; align-items: center; font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .12em; padding: 2px 9px; border-radius: var(--r-xs); color: var(--gold-text);
  background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.wb-ep-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.wb-ep-ops { display: flex; gap: var(--gap-xs); opacity: 0; transition: opacity .15s; }
.wb-card:hover .wb-ep-ops { opacity: 1; }
.wb-ep-ops button {
  width: 26px; height: 26px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all .13s;
}
.wb-ep-ops button svg { width: 12px; height: 12px; }
.wb-ep-ops button:hover { color: var(--gold); border-color: var(--line-strong); }
.wb-ep-title { font-family: var(--display); font-size: var(--fs-lg); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wb-ep-meta { font-size: var(--fs-xs); color: var(--ink-3); display: flex; gap: var(--sp-3); }
.wb-ep-meta b { color: var(--ink-2); font-weight: 700; font-family: var(--mono); }
.wb-ep-actions { margin-top: auto; display: flex; gap: var(--sp-2); }
.wb-script-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--gap-xs);
  padding: 7px var(--sp-3); border-radius: var(--r-sm); font-size: var(--fs-sm); font-weight: 700; cursor: pointer;
  border: 1px solid var(--line-strong); color: var(--gold-text); background: var(--surface-hover); transition: all .15s;
}
.wb-script-btn svg { width: 13px; height: 13px; }
.wb-script-btn:hover { background: var(--surface-3); }
.wb-script-btn.done { border-color: rgba(var(--ok-rgb), .4); color: var(--ok); background: rgba(var(--ok-rgb), .1); }

.wb-check {
  position: absolute; top: 10px; left: 10px; width: 20px; height: 20px; border-radius: var(--r-xs); z-index: 3;
  border: 1.5px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .7); color: transparent; cursor: pointer;
  display: none; align-items: center; justify-content: center;
}
.wb-check svg { width: 11px; height: 11px; stroke-width: 3; }
.wb-check.on { color: var(--gold-ink); background: var(--gold); border-color: var(--gold); }
body.wb-batch .wb-check { display: flex; }
body.wb-batch .wb-ep-num { margin-left: 26px; }
body.wb-batch .wb-ep-ops { display: none; }
.wb-batchbar { bottom: 96px; }

.wb-ai { flex-shrink: 0; padding: var(--sp-3) var(--sp-6) var(--sp-5); background: var(--surface); border-top: 1px solid var(--line); }
.wb-ai-inner {
  display: flex; align-items: center; gap: var(--sp-3); max-width: 820px; margin: 0 auto;
  padding: 5px 5px 5px var(--sp-4); border-radius: var(--r-full);
  background: rgba(var(--film), .03); border: 1px solid var(--line-strong); transition: border-color .18s;
}
.wb-ai-inner:focus-within { border-color: var(--gold); box-shadow: var(--ring); }
.wb-ai-tag {
  flex-shrink: 0; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .16em; padding: 3px 9px;
  border-radius: var(--r-xs); background: var(--gold-fill); color: var(--gold-ink);
}
.wb-ai-input { flex: 1; min-width: 0; background: none; border: none; outline: none; color: var(--ink); font-size: var(--fs-md); font-family: var(--font); }
.wb-ai-input::placeholder { color: var(--ink-3); }
.wb-ai-send {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-md); padding: 0 var(--sp-5);
  border: none; border-radius: var(--r-full); background: var(--gold-fill); color: var(--gold-ink);
  font-size: var(--fs-md); font-weight: 700; cursor: pointer; transition: background .15s;
}
.wb-ai-send svg { width: 15px; height: 15px; }
.wb-ai-send:hover { background: var(--gold-fill-h); }
.wb-ai-send:disabled { opacity: .5; cursor: not-allowed; }

.wb-empty {
  grid-column: 1 / -1; text-align: center; padding: var(--sp-10) var(--sp-5); color: var(--ink-3); font-size: var(--fs-md);
  border: 1px dashed var(--line-strong); border-radius: var(--r-md); background: rgba(var(--film), .015);
}

/* ---------- 19. 分镜工作台(ws-*) ---------- */
.ws {
  height: 100%; min-height: 0; display: flex; flex-direction: column;
  background: var(--bg); color: var(--ink);
}
.ws-bar {
  flex-shrink: 0; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-2) var(--sp-6); border-bottom: 1px solid var(--line); background: var(--surface);
}
.ws-bar-count { display: inline-flex; align-items: baseline; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.ws-bar-count .mbar-num { font-family: var(--mono); font-size: var(--fs-xl); font-weight: 700; letter-spacing: 0; color: var(--gold-text); }
.mbar-running {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 3px 10px; border-radius: var(--r-full);
  font-size: var(--fs-xs); font-weight: 700; color: var(--gold-text); background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.mbar-running svg { width: 12px; height: 12px; animation: spin 1.1s linear infinite; }
.mbar-hint { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.mbar-hint svg { width: 12px; height: 12px; opacity: .7; }
.ws-save-state {
  display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3);
  cursor: pointer; white-space: nowrap; user-select: none; transition: color .15s;
}
.ws-save-state::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ws-save-state[data-state="pending"] { color: var(--ink-2); }
.ws-save-state[data-state="saving"] { color: var(--gold-text); }
.ws-save-state[data-state="saved"] { color: var(--ok); }
.ws-save-state[data-state="error"] { color: var(--danger); }

.ws-tbtn {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-sm); padding: 0 var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: none; color: var(--ink-2);
  font-size: var(--fs-sm); font-weight: 600; cursor: pointer; white-space: nowrap; transition: all .15s;
}
.ws-tbtn svg { width: 13px; height: 13px; }
.ws-tbtn:hover { color: var(--ink); border-color: var(--line-strong); background: var(--surface-hover); }
.ws-tbtn:active { transform: scale(.97); }
.ws-tbtn.gold { background: var(--gold-fill); border-color: transparent; color: var(--gold-ink); font-weight: 700; }
.ws-tbtn.gold:hover { background: var(--gold-fill-h); }

.ws-body { flex: 1; min-height: 0; display: flex; gap: var(--sp-4); padding: var(--sp-4) var(--sp-6); overflow: hidden; }

/* 左栏 · 参考资产 */
.ws-left { width: 292px; flex-shrink: 0; min-height: 0; height: 100%; overflow: hidden; transition: width .2s ease; }
.ws-left.folded { width: 52px; display: flex; }
.ws-left.folded .ws-ref { display: none; }
.ws-left .ws-left-open { display: none; }
.ws-left.folded .ws-left-open { display: flex; width: 100%; height: 100%; }
.ws-ref {
  height: 100%; max-height: 100%; display: flex; flex-direction: column; gap: var(--sp-3); min-height: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--sp-4); overflow: hidden; box-shadow: var(--elev-2);
}
.ws-ref-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); flex-wrap: wrap; }
.ws-ref-head-right { display: flex; align-items: center; gap: var(--gap-xs); }
.ws-ref-kicker { width: 100%; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3); }
.ws-ref-title { font-size: var(--fs-md); font-weight: 700; }
.ws-ref-count {
  min-width: var(--h-2xs); height: var(--h-2xs); padding: 0 var(--gap-xs); border-radius: var(--r-full); display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700; color: var(--gold-text);
  background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.ws-ref-fold {
  width: var(--sq-sm); height: var(--sq-sm); padding: 0; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: none; color: var(--ink-3); cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.ws-ref-fold svg { width: 13px; height: 13px; }
.ws-ref-fold:hover { color: var(--gold); border-color: var(--line-strong); }
.ws-ref-quick { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-xs); }
.ws-ref-quick button {
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 7px 0 6px;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: rgba(var(--film), .02);
  color: var(--ink-2); font-size: var(--fs-xs); cursor: pointer; transition: all .15s;
}
.ws-ref-quick button svg { width: 14px; height: 14px; opacity: .7; }
.ws-ref-quick button:hover { border-color: var(--line-strong); color: var(--gold-text); background: var(--surface-hover); }
.ws-ref-frame {
  width: 100%; padding: 9px 0; border: none; border-radius: var(--r-sm); cursor: pointer;
  background: var(--gold-fill); color: var(--gold-ink); font-size: var(--fs-sm); font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--gap-xs); transition: background .15s;
}
.ws-ref-frame svg { width: 14px; height: 14px; }
.ws-ref-frame:hover { background: var(--gold-fill-h); }
.ws-ref-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-wrap: wrap; gap: var(--sp-2); align-content: flex-start; }
.ws-ref-item {
  position: relative; width: calc(50% - 4px); padding: 5px; overflow: hidden; text-align: left; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); transition: all .15s;
}
.ws-ref-item img { width: 100%; height: 62px; object-fit: cover; border-radius: 5px; background: var(--bg-deep); }
.ws-ref-ico { width: 100%; height: 62px; display: flex; align-items: center; justify-content: center; border-radius: 5px; background: var(--surface-sunk); color: var(--ink-2); }
.ws-ref-ico svg { width: 22px; height: 22px; }
.ws-ref-name { display: block; padding: 6px 3px 2px; font-size: var(--fs-xs); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-ref-tag {
  position: absolute; top: 8px; left: 8px; font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 5px;
  background: rgba(var(--scrim-rgb), .8); color: var(--scrim-accent); border: 1px solid var(--scrim-line);
}
.ws-ref-zoom {
  position: absolute; right: 6px; bottom: 24px; width: 24px; height: 24px; border-radius: var(--r-sm);
  display: grid; place-items: center; cursor: zoom-in;
  background: rgba(var(--scrim-rgb), .8); border: 1px solid var(--scrim-line); color: var(--scrim-ink);
  opacity: 0; transition: opacity .15s, background .15s;
}
.ws-ref-zoom svg { width: 11px; height: 11px; }
.ws-ref-item:hover .ws-ref-zoom { opacity: 1; }
.ws-ref-zoom:hover { background: var(--gold); color: var(--gold-ink); }
/* 选中态在角标旁给出「已选」标记,否则只能靠一圈金边判断 */
.ws-ref-item.sel::before {
  content: '已选'; position: absolute; right: 6px; top: 6px; z-index: 2;
  font-size: var(--fs-xs); font-weight: 700; padding: 1px 6px; border-radius: 5px;
  background: var(--gold); color: var(--gold-ink);
}
.ws-ref-item:hover { border-color: var(--line-strong); }
.ws-ref-item.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
.ws-ref-del {
  position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; padding: 0; border-radius: var(--r-xs);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .78); color: var(--scrim-ink); cursor: pointer;
  display: none; align-items: center; justify-content: center;
}
.ws-ref-del svg { width: 11px; height: 11px; }
.ws-ref-item:hover .ws-ref-del { display: inline-flex; }
.ws-ref-del:hover { color: var(--danger); border-color: rgba(var(--danger-rgb), .5); }
.ws-ref-empty {
  width: 100%; flex: 1; min-height: 128px; border: 1.5px dashed var(--line-strong); border-radius: var(--r-sm);
  background: rgba(var(--film), .015); color: var(--ink-2); font-size: var(--fs-md); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--gap-xs); transition: all .15s;
}
.ws-ref-empty span { font-size: var(--fs-xs); color: var(--ink-3); }
.ws-ref-empty:hover { border-color: var(--gold); color: var(--gold-text); background: var(--surface-hover); }
.ws-left-open {
  border-radius: var(--r-md); border: 1px solid var(--line); background: var(--surface); color: var(--gold);
  cursor: pointer; flex-direction: column; align-items: center; gap: var(--sp-2); padding: var(--sp-3) 0; transition: all .15s;
}
.ws-left-open:hover { border-color: var(--line-strong); background: var(--surface-2); }
.ws-left-open-ico {
  width: 28px; height: 28px; border-radius: var(--r-sm); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.ws-left-open-ico svg { width: 15px; height: 15px; }
.ws-left-open-count {
  min-width: var(--h-2xs); height: var(--h-2xs); padding: 0 var(--gap-xs); border-radius: var(--r-full);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700; color: var(--gold-text);
  background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.ws-left-open-label { writing-mode: vertical-lr; letter-spacing: .24em; font-size: var(--fs-xs); color: var(--ink-2); flex: 1; min-height: 0; display: flex; align-items: center; }

/* 主区 · 分镜卡 */
.ws-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: var(--sp-4); overflow-y: auto; padding-bottom: var(--sp-2); }
.ws-card {
  position: relative; flex-shrink: 0; display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--elev-2); transition: border-color .18s, box-shadow .18s;
}
.ws-card:hover { border-color: var(--line-strong); }
.ws-card.sel, .ws-card.is-collapsed { border-color: var(--line-strong); }
.ws-card.is-collapsed { border-left: 3px solid var(--gold); }
.ws-card.is-collapsed .ws-card-body { display: none; }
.ws-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: 10px var(--sp-4) 8px; cursor: pointer; }
.ws-card-head:hover { background: var(--surface-hover); }
.ws-card-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ws-shot-idx {
  display: inline-flex; align-items: center; gap: var(--gap-xs); flex-shrink: 0;
  font-family: var(--mono); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 9px; border-radius: var(--r-xs); color: var(--gold-text); background: var(--surface-hover); border: 1px solid var(--line-strong);
}
.ws-shot-idx svg { width: 11px; height: 11px; }
.ws-shot-title {
  flex: 1; min-width: 0; max-width: 340px; padding: 4px 9px; margin: -2px 0;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-sm);
  color: var(--ink); font-size: var(--fs-lg); font-weight: 600; font-family: var(--font); outline: none; cursor: text;
}
.ws-shot-title:hover { border-color: var(--line); background: rgba(var(--film), .02); }
.ws-shot-title:focus { border-color: var(--gold); background: var(--surface-2); box-shadow: var(--ring); }
.ws-card-actions { display: flex; align-items: center; gap: var(--gap-xs); flex-shrink: 0; }
.ws-icon-btn {
  width: var(--sq-sm); height: var(--sq-sm); padding: 0; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: none; color: var(--ink-3); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: all .13s;
}
.ws-icon-btn svg { width: 12px; height: 12px; }
.ws-icon-btn:hover { color: var(--gold); border-color: var(--line-strong); }
.ws-icon-btn.danger:hover { color: var(--danger); border-color: rgba(var(--danger-rgb), .5); }
.ws-icon-btn:disabled { opacity: .3; cursor: not-allowed; }
.ws-card-summary { padding: 0 var(--sp-4) 10px; margin: 0; font-size: var(--fs-xs); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-card-summary b { color: var(--gold-text); font-weight: 700; }
.ws-card-body { display: flex; flex-direction: column; min-height: 0; }
.ws-card-grid { display: grid; grid-template-columns: 288px minmax(0, 1fr); }

/* 参数栏 */
.ws-shot-params {
  display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0;
  border-right: 1px solid var(--line); background: rgba(var(--film), .014); padding: var(--sp-3) var(--sp-4) var(--sp-4);
}
.ws-param { display: flex; flex-direction: column; align-items: stretch; gap: var(--gap-xs); min-width: 0; }
.ws-param > label {
  display: inline-flex; align-items: center; gap: var(--gap-xs);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
}
.ws-param > label svg { width: 12px; height: 12px; color: var(--gold); opacity: .75; }
.ws-param > label b { margin-left: auto; min-width: 34px; text-align: right; font-family: var(--mono); font-size: var(--fs-md); letter-spacing: 0; color: var(--gold-text); }
.ws-select, .ws-input {
  width: 100%; min-width: 0; padding: 7px 10px; border-radius: var(--r-sm);
  background: rgba(var(--film), .03); border: 1px solid var(--line); color: var(--ink);
  font-size: var(--fs-sm); font-family: var(--font); outline: none; transition: border-color .15s, box-shadow .15s;
}
.ws-select:focus, .ws-input:focus { border-color: var(--gold); box-shadow: var(--ring); }
.ws-select-sm { padding: 6px 8px; font-size: var(--fs-xs); text-overflow: ellipsis; }
.ws-param-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3) var(--sp-2); }
.ws-pcell { display: flex; flex-direction: column; gap: var(--gap-xs); min-width: 0; }
.ws-pcell > label { display: inline-flex; align-items: center; gap: var(--gap-xs); min-width: 0; white-space: nowrap; font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); }
.ws-pcell > label svg { width: 11px; height: 11px; flex-shrink: 0; color: var(--gold); opacity: .75; }
.ws-param-motion { gap: 2px; }
.ws-param-motion input[type="range"] { width: 100%; height: 20px; }
.seed-row { display: flex; gap: var(--gap-xs); }
.seed-row .ws-input { flex: 1; min-width: 0; }
.seed-row .ws-icon-btn { width: 32px; height: 32px; flex-shrink: 0; }

/* 文案栏 */
.ws-shot-editor { min-width: 0; display: flex; flex-direction: column; }
.ws-editor-cap {
  display: flex; align-items: center; gap: var(--sp-2); padding: 10px var(--sp-5) 0;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
}
.ws-editor-cap svg { width: 12px; height: 12px; color: var(--gold); }
.ws-editor-cap span { margin-left: auto; font-weight: 400; letter-spacing: 0; text-transform: none; font-size: var(--fs-xs); color: var(--ink-3); }
.ws-script-wrap { padding: var(--sp-2) var(--sp-5) var(--sp-2); }
/* 剧本正文 15px / 行高 1.85 是 [占位符] 镜像对齐的调校值(plink.js 按此测量令牌宽度),
   不并入通用字号阶:改动会让令牌与真实文本错位、长名被截断 */
.ws-script {
  width: 100%; min-height: 132px; resize: vertical; padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md); background: rgba(var(--film), .03); border: 1px solid var(--line);
  color: var(--ink); font-size: 15px; font-family: var(--font); line-height: 1.85; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.ws-script:focus { border-color: var(--gold); box-shadow: var(--ring); }
.ws-script::placeholder { color: var(--ink-3); }
.ws-pl-chips { padding: 0 var(--sp-5); }
/* 融生视频缺源图时的前置条件提示:不再等到点「生成」才抛 toast。
   源图本身不做常驻显示 —— 用哪个图由文案里的 [资产名] 引用决定 */
.ws-need-src {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  margin: 0 var(--sp-5) var(--sp-2); padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm); border: 1px solid rgba(var(--warn-rgb), .38); background: rgba(var(--warn-rgb), .07);
  color: var(--warn); font-size: var(--fs-sm);
}
.ws-need-src svg { width: 14px; height: 14px; flex-shrink: 0; }
.ws-need-src > span { flex: 1 1 200px; min-width: 0; }
.ws-need-src .btn { background: rgba(var(--film), .06); }
.ws-genbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; padding: var(--sp-2) var(--sp-5) var(--sp-4); margin-top: auto; }
.ws-neg {
  flex: 1; min-width: 160px; padding: 8px var(--sp-3); border-radius: var(--r-sm);
  background: rgba(var(--film), .03); border: 1px solid var(--line); color: var(--ink); font-size: var(--fs-sm); outline: none;
}
.ws-neg:focus { border-color: var(--gold); box-shadow: var(--ring); }
.ws-neg::placeholder { color: var(--ink-3); }
.ws-gen-btn {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 0 var(--sp-5); height: var(--h-md);
  border: none; border-radius: var(--r-sm); background: var(--gold-fill); color: var(--gold-ink);
  font-size: var(--fs-md); font-weight: 700; cursor: pointer; transition: background .15s;
}
.ws-gen-btn svg { width: 15px; height: 15px; }
.ws-gen-btn:hover { background: var(--gold-fill-h); }
.ws-gen-btn:disabled { opacity: .55; cursor: not-allowed; }

/* 生成记录 */
.ws-preview { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2) var(--sp-5) var(--sp-4); border-top: 1px dashed var(--line); }
.ws-preview:empty { display: none; }
.ws-preview-empty {
  min-height: 84px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm);
  border: 1.5px dashed var(--line); color: var(--ink-3); font-size: var(--fs-sm); letter-spacing: .04em;
}
.ws-recs-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); cursor: pointer; user-select: none;
  padding: 7px var(--sp-3); border-radius: var(--r-sm); background: var(--surface-hover); border: 1px solid var(--line); transition: all .15s;
}
.ws-recs-head:hover { border-color: var(--line-strong); }
.ws-recs-cap { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.ws-recs-cap svg { width: 12px; height: 12px; color: var(--gold); }
.ws-recs-cap b { font-family: var(--mono); font-size: var(--fs-md); font-weight: 700; letter-spacing: 0; color: var(--gold-text); }
.ws-recs-run { font-style: normal; font-size: var(--fs-xs); padding: 1px 8px; border-radius: var(--r-full); background: var(--surface-hover); border: 1px solid var(--line-strong); color: var(--gold-text); }
.ws-recs-toggle { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-sm); color: var(--ink-2); }
.ws-recs-toggle svg { width: 12px; height: 12px; transition: transform .16s; }
.ws-recs-head.is-collapsed .ws-recs-toggle svg { transform: rotate(180deg); }
.ws-recs-body { display: flex; flex-direction: column; gap: var(--sp-2); }
.ws-recs-body[hidden] { display: none; }
.ws-rec { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; transition: border-color .15s; }
.ws-rec:hover { border-color: var(--line-strong); }
.ws-rec.is-collapsed .ws-rec-media-wrap { display: none; }
.ws-rec-head { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); cursor: pointer; }
.ws-rec-info { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--sp-2); }
.ws-rec-info > div { min-width: 0; flex: 1; }
.ws-rec-thumb {
  width: 56px; height: 32px; border-radius: var(--r-xs); object-fit: cover; flex-shrink: 0;
  background: var(--bg-deep); border: 1px solid var(--line); cursor: zoom-in;
}
.ws-rec-title { font-size: var(--fs-md); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-rec-sub { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-rec-side { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; }
.ws-rec-acts { display: flex; gap: var(--gap-xs); }
.ws-rec-act {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: 26px; padding: 0 var(--sp-3);
  border-radius: var(--r-sm); font-size: var(--fs-xs); cursor: pointer; text-decoration: none; transition: all .13s;
  border: 1px solid var(--line-strong); color: var(--gold-text); background: var(--surface-hover);
}
.ws-rec-act svg { width: 12px; height: 12px; }
.ws-rec-act:hover { background: var(--surface-3); text-decoration: none; }
.ws-rec-act.danger, .ws-rec-act.danger svg { color: var(--danger); border-color: rgba(var(--danger-rgb), .4); background: rgba(var(--danger-rgb), .08); }
.ws-rec-act.danger:hover { background: rgba(var(--danger-rgb), .16); }
.ws-rec-toggle {
  width: 26px; height: 26px; border-radius: var(--r-sm); border: 1px solid var(--line); background: none; color: var(--ink-3);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.ws-rec-toggle svg { width: 12px; height: 12px; transition: transform .16s; }
.ws-rec-toggle svg.rotate { transform: rotate(180deg); }
.ws-rec-toggle:hover { color: var(--gold); border-color: var(--line-strong); }
.ws-rec-media-wrap { padding: 0 var(--sp-3) var(--sp-3); max-width: 100%; }
.ws-rec-progress {
  width: 100%; min-height: 84px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-sm); color: var(--gold-text); font-size: var(--fs-sm); font-family: var(--mono);
}
.ws-rec-bar { width: 78%; height: 5px; background: rgba(var(--film), .08); border-radius: var(--r-full); overflow: hidden; }
.ws-rec-bar i { display: block; height: 100%; background: var(--gold-fill); border-radius: var(--r-full); transition: width .4s; }
.ws-rec-fail {
  width: 100%; min-height: 60px; display: flex; align-items: center; justify-content: center; padding: var(--sp-2) var(--sp-3);
  border: 1px dashed rgba(var(--danger-rgb), .4); border-radius: var(--r-sm); color: var(--danger); font-size: var(--fs-sm); text-align: center;
}
.ws-rec-cover {
  position: relative; width: min(320px, 100%); aspect-ratio: 16 / 9; border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-deep); cursor: zoom-in;
}
.ws-rec-cover img { width: 100%; height: 100%; object-fit: cover; opacity: .92; transition: transform .2s ease, opacity .2s ease; }
.ws-rec-cover:hover img { transform: scale(1.04); opacity: 1; }
.ws-rec-play {
  position: absolute; inset: 0; margin: auto; width: 42px; height: 42px; border-radius: 50%;
  background: rgba(var(--scrim-rgb), .62); border: 1px solid var(--scrim-line); color: var(--scrim-ink);
  display: grid; place-items: center; pointer-events: none; transition: transform .18s ease, background .18s ease;
}
.ws-rec-play svg { width: 18px; height: 18px; }
.ws-rec-cover:hover .ws-rec-play { transform: scale(1.1); background: rgba(var(--scrim-rgb), .8); }
.ws-rec-dur {
  position: absolute; right: 7px; bottom: 7px; font-family: var(--mono); font-size: var(--fs-xs);
  color: var(--scrim-ink); background: rgba(var(--scrim-rgb), .7); border-radius: 5px; padding: 2px 6px; pointer-events: none;
}

/* 剪辑预览 */
.ws-edit-preview { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--sp-3); }
.ws-clip-scene { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-4); }
.ws-clip-scene-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); font-weight: 700; font-size: var(--fs-md); }
.ws-clip-scene-head svg { width: 14px; height: 14px; color: var(--gold); }
.ws-clip-count { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 400; }
.ws-clip-row { display: flex; gap: var(--sp-3); overflow-x: auto; padding-bottom: 5px; }
.ws-clip { flex-shrink: 0; width: 168px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; transition: border-color .15s; }
.ws-clip:hover { border-color: var(--line-strong); }
.ws-clip img, .ws-clip video { width: 100%; height: 94px; object-fit: cover; background: var(--bg-deep); }
.ws-clip span { display: block; padding: 7px 9px; font-size: var(--fs-xs); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-clip-none { color: var(--ink-3); font-size: var(--fs-sm); padding: var(--sp-3) var(--sp-1); }

.ws-foot { flex-shrink: 0; padding: var(--sp-2) var(--sp-6) var(--sp-5); }
.ws-add-shot {
  width: 100%; padding: var(--sp-3) 0; border-radius: var(--r-md); cursor: pointer;
  border: 1.5px dashed var(--line-strong); background: rgba(var(--film), .015); color: var(--gold-text);
  font-size: var(--fs-md); font-weight: 700; letter-spacing: .1em; transition: all .18s;
}
.ws-add-shot:hover { background: var(--surface-hover); border-style: solid; border-color: var(--gold); }

/* 弹窗复用件 */
.ws-review-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.ws-review-item { display: flex; align-items: center; gap: var(--sp-3); padding: 10px var(--sp-3); border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); }
.ws-review-main { flex: 1; min-width: 0; }
.ws-review-title { font-size: var(--fs-md); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-review-sub { font-size: var(--fs-xs); color: var(--ink-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ws-review-acts { display: flex; gap: var(--gap-xs); flex-shrink: 0; }
.ws-log-filter { display: flex; align-items: center; gap: var(--gap-xs); margin-bottom: var(--sp-3); flex-wrap: wrap; }
.wpk-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-sm); padding: 0 var(--sp-3);
  border-radius: var(--r-full); border: 1px solid var(--line); background: none; color: var(--ink-2);
  font-size: var(--fs-sm); font-weight: 600; cursor: pointer; transition: all .15s;
}
.wpk-chip:hover { color: var(--ink); border-color: var(--line-strong); }
.wpk-chip.on { background: var(--sel-fill); border-color: var(--sel-line); color: var(--sel-ink); }
.wpk-chip i { font-style: normal; opacity: .7; }
.ws-pick-hint { font-size: var(--fs-sm); color: var(--ink-2); }
.ws-pick-empty { padding: var(--sp-8); text-align: center; color: var(--ink-3); font-size: var(--fs-sm); }
.ws-log-item { display: flex; flex-direction: column; gap: var(--sp-2); padding: 10px var(--sp-3); border-radius: var(--r-sm); background: var(--surface-2); border: 1px solid var(--line); cursor: pointer; }
.ws-log-item.is-normal { border-left: 3px solid rgba(var(--ok-rgb), .5); }
.ws-log-item.is-abnormal { border-left: 3px solid rgba(var(--danger-rgb), .5); }
.ws-log-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ws-log-state { display: inline-flex; align-items: center; font-size: var(--fs-xs); font-weight: 700; padding: 2px 9px; border-radius: var(--r-full); }
.ws-log-state.ok { background: rgba(var(--ok-rgb), .14); color: var(--ok); border: 1px solid rgba(var(--ok-rgb), .4); }
.ws-log-state.bad { background: rgba(var(--danger-rgb), .12); color: var(--danger); border: 1px solid rgba(var(--danger-rgb), .4); }
.ws-log-time { margin-left: auto; font-size: var(--fs-xs); color: var(--ink-3); }
.wl-detail { margin-top: 5px; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); background: rgba(var(--film), .025); border: 1px solid var(--line); font-size: var(--fs-sm); line-height: 1.8; }
.wl-detail-row { color: var(--ink-2); }
.wl-detail-row b { color: var(--gold-text); font-weight: 700; }
.wl-detail-row code { font-family: var(--mono); font-size: var(--fs-xs); color: var(--ink-3); background: rgba(var(--film), .05); padding: 1px 5px; border-radius: 4px; }
.wl-detail-err { color: var(--danger); }
.wl-detail-btn { margin-left: auto; }
.alib-toolbar { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); flex-wrap: wrap; }
.alib-count { font-size: var(--fs-sm); color: var(--ink-2); white-space: nowrap; }
.alib-count b, .gold-num { color: var(--gold-text); font-family: var(--mono); }
.ws-tbtn span, .wb-tbtn span { line-height: 1; }
.alib-body { display: flex; gap: var(--sp-4); align-items: flex-start; min-height: 300px; }
/* 26·4:弹窗内的资产列表不再自带滚动条 —— 弹窗内容区(.modal-body)是唯一的滚动容器,
   此前「列表滚动 + 弹窗滚动」两条叠在一起,滚轮经常抓错容器 */
.alib-side { width: 184px; flex-shrink: 0; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 6px; }
.alib-side-head { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); padding: 5px var(--sp-2) var(--sp-2); border-bottom: 1px solid var(--line); margin-bottom: 5px; }
.alib-main { flex: 1; min-width: 0; }
.alib-main .grid-cards { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: var(--sp-3); }
.alib-body .media-card { cursor: pointer; }
.task-prompt-btn {
  border: none; background: none; padding: 0; cursor: pointer; font-size: var(--fs-sm); color: var(--ok); text-align: left;
  max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.task-prompt-btn:hover { text-decoration: underline; }
.preview-info-row { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 5px 0; border-bottom: 1px dashed var(--line); font-size: var(--fs-sm); color: var(--ink-2); }
.preview-info-row span:first-child { color: var(--ink-3); }
.preview-info-row span:last-child { color: var(--ink); font-family: var(--mono); font-size: var(--fs-xs); }

/* ---------- 20. 资产库 ---------- */
.ast-layout { display: flex; gap: var(--sp-4); align-items: start; }
/* 26·7:文件夹栏跟随页面滚动(此前向下一滚就脱离了视野) */
.ast-side { width: 208px; flex-shrink: 0; position: sticky; top: var(--sp-4); }
.ast-side .card { padding: var(--sp-3); margin-bottom: 0; }
.ast-side-title { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); padding: 0 var(--sp-2) var(--sp-2); }
.ast-main { flex: 1; min-width: 0; }
.folder-tree { display: flex; flex-direction: column; gap: 1px; }
.folder-item {
  display: flex; align-items: center; gap: var(--gap-xs); padding: 7px var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-md); color: var(--ink-2); cursor: pointer; border: 1px solid transparent; transition: all .14s;
}
.folder-item:hover { background: var(--surface-hover); color: var(--ink); }
.folder-item svg { width: 14px; height: 14px; color: var(--ink-3); flex-shrink: 0; }
.folder-item.active { background: var(--sel-soft); color: var(--sel-soft-ink); border-color: var(--sel-soft-line); }
.folder-item.active svg { color: var(--gold); }
.alib-fname { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.select-box {
  position: fixed; z-index: 9999; pointer-events: none;
  border: 1.5px solid var(--gold); background: rgba(var(--accent-rgb), .12); border-radius: var(--r-xs);
}

/* ---------- 21. 风格库 ---------- */
#styleGrid { grid-template-columns: repeat(auto-fill, minmax(252px, 1fr)); }
#styleGrid .card { display: flex; flex-direction: column; margin-bottom: 0; }
#styleGrid .card { display: flex; flex-direction: column; }
#styleGrid .card > div:last-child { margin-top: auto; }
.st-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.st-name { font-size: var(--fs-lg); font-weight: 700; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-meta { font-size: var(--fs-sm); color: var(--ink-2); margin-bottom: 5px; }
.st-desc {
  font-size: var(--fs-sm); color: var(--ink-3); line-height: 1.65; margin-bottom: var(--sp-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.st-tags { display: flex; flex-wrap: nowrap; gap: var(--gap-xs); margin-bottom: var(--sp-3); overflow: hidden; min-height: 20px; }
.st-tags .tag { margin: 0; }
.st-actions { display: flex; gap: var(--gap-xs); }
.fav-btn { width: var(--sq-md); height: var(--sq-md); border-radius: var(--r-sm); }
.fav-btn svg { width: 14px; height: 14px; transition: transform .16s ease; }
.fav-btn:hover svg { transform: scale(1.15); }
.fav-btn.on svg { fill: var(--warn); color: var(--warn); }

/* ---------- 22. AI 生图 ---------- */
/* ---------- 需求三十四:创作台(composer 置顶) ----------
   原来 392px 侧栏 + 右栏内部滚动是「管理表单」的排法:主次不分,提示词被压在窄栏里,
   参考图藏在按钮后面。改成上下两段 —— 创作台占满整幅、参数收进右侧列,下面整幅给记录画布。 */
.ig-studio { display: flex; flex-direction: column; gap: var(--sp-4); }
.ig-composer { margin-bottom: 0; padding: var(--sp-4); }
.igc-top { display: grid; grid-template-columns: minmax(0, 1fr) 322px; gap: var(--sp-4); align-items: stretch; }
.igc-lbl { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); margin-bottom: 5px; }
.igc-main { display: flex; flex-direction: column; min-width: 0; }
/* 右侧列加了比例胶囊后比左列高,让提示词框吃掉这段差值 —— 生图工具里提示词框大点本来就好写 */
.igc-prompt { flex: 1 1 auto; min-height: 112px; resize: vertical; font-size: var(--fs-md); line-height: 1.65; }
.igc-side { display: flex; flex-direction: column; gap: var(--sp-2); border-left: 1px solid var(--line); padding-left: var(--sp-4); }
.igc-side .field { margin-bottom: 0; }
.igc-spec { display: flex; gap: var(--gap-xs); flex-wrap: wrap; }
.igc-grp { display: flex; flex-direction: column; gap: 3px; }
.igc-grp > .igc-grp-k { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 700; }
/* 画幅比例:形状按真实比例画,长边 18px —— 选画幅是看一眼就要点定的事,不该藏在下拉里 */
.ig-ratios { display: flex; flex-wrap: wrap; gap: var(--gap-xs); }
.ig-ratio {
  display: inline-flex; flex-direction: column; align-items: center; gap: 3px; min-width: 46px;
  padding: 5px 6px 4px; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-xs); font-weight: 700; cursor: pointer; transition: all .14s;
}
.ig-ratio i { display: block; border: 1.5px solid currentColor; border-radius: 2px; opacity: .7; }
.ig-ratio:hover { color: var(--ink); border-color: var(--line-strong); }
.ig-ratio.on { border-color: var(--sel-line); background: var(--sel-fill); color: var(--sel-ink); }
.igc-pill { flex: 1 1 82px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.igc-pill > span { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 700; }
.igc-pill .select { height: var(--h-sm); font-size: var(--fs-sm); }
/* 折叠区:负面提示词与低频参数都收起来,首屏只留提示词与主行动 */
.igc-fold { display: flex; flex-direction: column; min-height: 0; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2); }
.igc-fold > summary { flex: 0 0 auto; display: flex; align-items: center; gap: var(--gap-xs); cursor: pointer; list-style: none; padding: 7px 10px; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); }
.igc-fold > summary::-webkit-details-marker { display: none; }
.igc-fold > summary:hover { color: var(--ink); }
.igc-fold[open] > summary { border-bottom: 1px solid var(--line); }
/* 展开区定高 + 内部滚动:创作台左列是定高的,展开内容一旦超出就会盖到下面的规格横条上
   (实测两栏都展开时溢出 383px,提示词记录直接压在生成记录标题上) */
.igc-fold-body { flex: 0 1 auto; min-height: 0; max-height: 132px; overflow-y: auto; margin: 6px 10px 10px; }
.igc-side .igc-fold > *:not(summary) { margin: 6px 8px 8px; }
.ig-neg-sum { margin-left: auto; font-size: var(--fs-xs); color: var(--ink-3); font-weight: 600; font-variant-numeric: tabular-nums; }
.igc-go-row { display: flex; flex-direction: column; align-items: stretch; gap: var(--gap-xs); margin-top: var(--sp-2); }
.igc-go-row .ig-go { flex: 0 0 auto; min-width: 0; padding: 0 var(--sp-3); }
/* 成本提示是 nowrap 药丸,和按钮并排时 322px 侧列根本放不下,整行冲出创作台被切掉 */
.ig-go-cost {
  display: inline-flex; align-items: center; margin-left: 2px; padding: 1px 9px;
  border-radius: var(--r-full); background: rgba(255, 255, 255, .22);
  font-size: var(--fs-xs); font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.5;
}
/* 参考图组合:三槽位(参考站同款),自定义上传单独一行 */
/* 规格横条:比例胶囊 + 分辨率 + 张数 + 输出读数 + 低频参数,整幅一行排开 */
.igc-bar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px dashed var(--line-strong); }
.igc-bar-k { font-size: var(--fs-xs); color: var(--ink-3); font-weight: 700; }
.igc-pill-sel { flex: 0 0 auto; min-width: 88px; }
.igc-pill-sel .select { height: var(--h-sm); font-size: var(--fs-sm); }
.igc-bar .ig-spec-out { margin: 0; }
/* 「更多参数」是低频入口,展开做成浮层而不是把规格横条撑高 ——
   横条一长高,下面的参考图托盘整块下移,又是同一种「点一下就跳版」 */
.igc-fold-inline { position: relative; background: var(--surface-2); }
.igc-fold-inline > summary { padding: 5px 10px; }
.igc-fold-inline .igc-fold-body {
  position: absolute; z-index: 45; right: 0; top: calc(100% + 6px); margin: 0;
  display: flex; flex-direction: column; gap: var(--gap-xs);
  width: 268px; max-height: 240px; padding: 10px; overflow: visible;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md); box-shadow: var(--elev-2);
}
.igc-fold-inline[open] > summary { border-bottom: none; }
/* 窄屏下规格横条会折行,「更多参数」可能落在行的中段:再往右挂就冲出视口左边界 */
@media (max-width: 720px) {
  .igc-fold-inline .igc-fold-body { left: 0; right: auto; width: 240px; }
}
.igc-fold-inline .igc-fold-body .igc-pill { flex: 1 1 100% }
.igc-fold-inline .igc-fold-body .ig-seed-row { margin-top: var(--gap-xs) }
.igc-refs { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px dashed var(--line-strong); }
.igc-refs-head { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.igc-refs-head > b { font-size: var(--fs-sm); }
.igc-sp { flex: 1 1 auto; }
/* 参考图托盘:紧凑横条芯片(照参考站),空位是「+ 选人像」这种幽灵按钮。
   整条托盘是一个「拖进来就行」的落区 —— 1920 下空托盘右侧原本空着 1354px,
   与其留一片白,不如把它做成有形状的投放区(从桌面直接拖图片进来就能当参考图)。 */
.ig-slots {
  display: flex; flex-wrap: wrap; align-content: flex-start; gap: var(--gap-xs);
  min-height: 76px; margin-bottom: 6px; padding: 8px;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2);
  transition: border-color .14s, background .14s;
}
.ig-slots.drag { border-color: var(--gold); background: var(--sel-soft); }
/* 需求三十七·1(排版照 ai-pose-gallery studio):一格一个圆角容器,芯片/选图按钮住在里面 */
.ig-slot-box {
  display: flex; align-items: center; gap: 6px; min-height: 60px; padding: 6px;
  border-radius: var(--r-md); border: 1px solid var(--line-strong); background: var(--surface);
  flex: 1 1 250px; max-width: 470px; transition: all .14s; text-align: left;
}
.ig-slot-pick {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px; padding: 6px 8px;
  border: none; background: none; color: var(--ink-3); font-size: var(--fs-sm); font-weight: 600;
  cursor: pointer; transition: color .14s; text-align: left;
}
.ig-slot-pick .ico { flex: 0 0 auto; width: 22px; height: 22px; padding: 4px; box-sizing: content-box;
  color: var(--ink-3); background: var(--surface-2); border-radius: var(--r-xs); transition: all .14s; }
.ig-slot-pick:hover { color: var(--ink); }
.ig-slot-pick:hover .ico { color: var(--gold); background: var(--surface-hover); }
/* 空格右侧内嵌的「资产」动作钮:浅一档的实底小钮,像参考图里组内的「上传」 */
.ig-slot-act {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; height: 32px; padding: 0 10px;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink-2); font-size: var(--fs-xs); font-weight: 600; cursor: pointer; transition: all .14s; white-space: nowrap;
}
.ig-slot-act:hover { border-color: var(--gold); color: var(--ink); background: var(--surface-hover); }
.ig-slot-act .ico { width: 12px; height: 12px; }
/* 自定义多选保留一条虚线格,整格可点 */
.ig-slot-box.is-dashed {
  border-style: dashed; background: none; color: var(--ink-3); cursor: pointer;
  justify-content: center; font-size: var(--fs-sm); font-weight: 600; padding: 6px 14px;
}
.ig-slot-box.is-dashed .ico { width: 14px; height: 14px; }
.ig-slot-box.is-dashed:hover { border-color: var(--gold); color: var(--ink); background: var(--surface-hover); }
/* 选了图的格:芯片自带边框取消,由外层容器统一描边 */
.ig-slot-box .ig-slot { flex: 1 1 auto; max-width: none; border: none; background: none; padding: 0; }
.ig-slot-box .ig-slot:hover { border: none; }
.ig-slot {
  position: relative; display: flex; align-items: center; gap: 8px; flex: 1 1 224px; max-width: 380px;
  padding: 6px 26px 6px 6px; border-radius: var(--r-md); border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--ink); cursor: pointer; text-align: left; transition: all .14s;
}
.ig-slot:hover { border-color: var(--gold); }
/* 缩略图里 cover 裁掉的部分,点开放大就都看得见 —— 不必为了「看得全」把卡片撑大 */
.ig-slot-media { position: relative; flex: 0 0 auto; width: 48px; height: 48px; border-radius: var(--r-xs); overflow: hidden; background: var(--bg-deep); cursor: zoom-in; }
.ig-slot-media img { width: 100%; height: 100%; object-fit: cover; }
.ig-slot-cap { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ig-slot-k { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); }
.ig-slot-n { font-size: var(--fs-sm); color: var(--ink); line-height: 1.35; max-width: 216px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ig-slot-x {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: var(--r-xs); border: none;
  background: rgba(var(--film), .08); color: var(--ink-3); cursor: pointer; display: grid; place-items: center; transition: all .14s;
}
.ig-slot-x:hover { background: rgba(var(--danger-rgb), .2); color: var(--danger); }
.ig-slot-x .ico { width: 12px; height: 12px; }
.ig-slot .ig-ref-idx { top: 2px; left: 2px; }
.ig-cap-row { display: flex; flex-wrap: wrap; gap: var(--gap-xs); margin-top: 6px; }
.ig-cap-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-2xs); padding: 0 9px;
  border-radius: var(--r-full); border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink-2); font-size: var(--fs-xs); font-weight: 600;
}
.ig-cap-chip .ico { width: 11px; height: 11px; color: var(--gold); }
.ig-ref-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.ig-ref-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: 34px; padding: 0 var(--sp-2) 0 5px;
  border-radius: var(--r-sm); border: 1px solid var(--line-strong); background: var(--surface-hover);
}
.ig-ref-thumb { width: 26px; height: 26px; border-radius: var(--r-xs); object-fit: cover; background: var(--bg-deep); }
.ig-ref-name { font-size: var(--fs-sm); max-width: 128px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ig-ref-x {
  width: 20px; height: 20px; border-radius: var(--r-xs); border: none; background: rgba(var(--film), .06);
  color: var(--ink-2); cursor: pointer; display: grid; place-items: center; transition: all .14s;
}
.ig-ref-x:hover { background: rgba(var(--danger-rgb), .2); color: var(--danger); }
.ig-ref-x .ico { width: 11px; height: 11px; }

/* ---------- 需求三十五:AI 优化提示词 / 提示词预设 / 槽位双来源 ---------- */
/* 提示词标签行:左「提示词 + 字数」,右「AI 优化」;按钮用 align-self 压回中线,
   不动 .igc-lbl 的 baseline(字数角标还要跟文字基线走) */
.igc-lbl-main { display: inline-flex; align-items: baseline; gap: var(--sp-2); min-width: 0; }
.ig-ai-opt { flex: 0 0 auto; align-self: center; gap: var(--gap-xs); }
.ig-ai-opt .ico { width: 13px; height: 13px; }
.ig-ai-opt:hover { border-color: var(--gold); color: var(--gold-text); }
/* 槽位单元格 = 芯片/幽灵钮 +(仅空格时)「资产」直入资产库标签(需求三十六·1);
   格里有图只留芯片,点芯片本体即可换图 —— 托盘不再一排上传按钮 */
/* 槽位选图器的「参考图库 / 项目资产库」标签页(需求三十五·3) */
.ig-src-tabs { display: flex; gap: var(--gap-xs); margin-bottom: var(--sp-2); }
.ig-src-tab {
  height: var(--h-sm); padding: 0 var(--sp-3); border-radius: var(--r-full); border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-sm); font-weight: 700;
  cursor: pointer; transition: all .14s;
}
.ig-src-tab:hover { color: var(--ink); border-color: var(--line-strong); }
.ig-src-tab.on { background: var(--sel-fill); border-color: var(--sel-line); color: var(--sel-ink); }
.ig-src-tab:disabled { opacity: .45; cursor: not-allowed; }
.ig-src-pane[hidden] { display: none; }
/* AI 优化弹窗(需求三十五·1):模型下拉与「开始优化」一行,原词只读置灰 */
.ig-opt-mrow { display: flex; gap: var(--gap-xs); }
.ig-opt-mrow .select { flex: 1 1 auto; min-width: 0; }
.ig-opt-mrow .btn { flex: 0 0 auto; white-space: nowrap; }
.ig-opt textarea[readonly] { color: var(--ink-3); background: var(--surface-2); }
/* 参考图挑选弹窗顶条:搜索占主宽,「上传图片」靠右(需求三十六·1) */
.ig-pick-bar { display: flex; gap: var(--gap-xs); margin-bottom: 10px; }
.ig-pick-bar .input { flex: 1 1 auto; min-width: 0; }
.ig-pick-bar .btn { flex: 0 0 auto; white-space: nowrap; }
/* 系统设置·生成默认:提示词预设编辑行(名称 / 提示词 / 负面词 / 启用 / 删除) */
.igp-rows { display: flex; flex-direction: column; gap: var(--gap-xs); margin-bottom: var(--gap-xs); }
.igp-row { display: grid; grid-template-columns: 110px minmax(0, 1.4fr) minmax(0, 1fr) 44px 34px; gap: var(--gap-xs); align-items: start; }
.igp-row.off { opacity: .55; }
.igp-row .textarea { font-size: var(--fs-xs); line-height: 1.5; }
.igp-on {
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding-top: 6px;
  font-size: var(--fs-xs); color: var(--ink-3); cursor: pointer; white-space: nowrap;
}
@media (max-width: 1100px) {
  .igp-row { grid-template-columns: 110px 1fr 34px; }
  .igp-on { flex-direction: row; padding-top: 0; align-self: center; }
  .igp-row .textarea:first-of-type { grid-column: 1 / -1; }
}

/* ---------- 需求三十二:负面提示词快选 + 参考图库 ---------- */
/* 快选词条是「可点的芯片」,与记录区筛选 chips 同一几何(--h-xs 28);
   不可点的能力标签才用 22px 那一档。22px 的词条在触屏上实测只有 42×22,按不准 */
.ig-neg-chips { display: flex; flex-wrap: wrap; gap: var(--gap-xs); margin-top: var(--gap-xs); }
.ig-neg-chips:empty { display: none; }
.ig-neg-chip {
  display: inline-flex; align-items: center; gap: 4px; height: var(--h-xs); padding: 0 10px;
  border-radius: var(--r-full); border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink-2); font-size: var(--fs-xs); font-weight: 600; cursor: pointer; transition: all .14s;
}
.ig-neg-chip i { font-style: normal; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.ig-neg-chip:hover { color: var(--ink); border-color: var(--line-strong); }
.ig-neg-chip.on { background: var(--sel-fill); border-color: var(--sel-line); color: var(--sel-ink); }
.ig-neg-chip.on i { color: inherit; opacity: .72; }
/* 负面词块预设编辑器(后台):芯片文字 + 整块内容 + 删除 */
.neg-list { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.neg-row { display: grid; grid-template-columns: 108px 1fr 34px; gap: var(--gap-xs); align-items: start; }
.neg-row .neg-text { min-height: 54px; font-size: var(--fs-sm); }
.neg-row .neg-del { height: 34px; padding: 0; display: grid; place-items: center; }
/* 生图页:参考图芯片上的「图N」角标 —— 与服务端配方说明里的编号对齐 */
.ig-ref-chip { position: relative; }
.ig-ref-idx {
  position: absolute; top: -6px; left: -5px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--r-full); background: var(--gold); color: var(--gold-ink);
  font-size: 10px; font-weight: 800; line-height: 17px; text-align: center; font-variant-numeric: tabular-nums;
}
/* 最近提示词(本机记录):一行一条,点一下回填 */
.ig-hist { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.ig-hist-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  padding: 5px 8px; border: 1px solid transparent; border-radius: var(--r-sm); background: none;
  color: var(--ink); font-size: var(--fs-sm); cursor: pointer; text-align: left;
}
.ig-hist-item:hover { background: var(--surface-hover); border-color: var(--line); }
.ig-hist-p { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ig-hist-t { flex: 0 0 auto; font-size: var(--fs-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.ig-hist-clear {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-end; margin-top: 2px;
  min-height: 28px; padding: 0 8px;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: none; color: var(--ink-3);
  font-size: var(--fs-xs); cursor: pointer;
}
.ig-hist-clear:hover { color: var(--danger); border-color: rgba(var(--danger-rgb), .5); }
.ig-hist-clear .ico { width: 11px; height: 11px; }
/* 图库配方芯片:同几何,虚线边区分「来自图库」而不是自己上传 */
.ig-gal-row:empty { display: none; }
.ig-gal-chip { border-style: dashed; }
.ig-gal-n { font-style: normal; color: var(--ink-3); font-variant-numeric: tabular-nums; margin-left: 3px; }
.ig-gal-opt { display: inline-flex; align-items: center; gap: var(--gap-xs); min-height: 28px; padding: 0 2px; font-size: var(--fs-xs); font-weight: 600; color: var(--ink-2); cursor: pointer; }
.ig-gal-opt input { width: 16px; height: 16px; margin: 0; accent-color: var(--gold); cursor: pointer; }
.ig-gal-bar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.ig-gal-kinds { display: flex; gap: var(--gap-xs); flex-wrap: wrap; }
.ig-gal-search { flex: 1; min-width: 190px; }
/* 悬停预览是这一轮新加的手势,不写一句就没人会去悬停 —— 一行小字,不占布局档位 */
.ig-gal-tip { flex: 0 0 auto; font-size: var(--fs-xs); color: var(--ink-3); font-weight: 600; }
.ig-gal-filters { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-bottom: var(--sp-2); }
/* 选项多的维度用下拉,和同排的芯片等高,不然一行里两个高度 */
.ig-gal-sel { display: inline-flex; align-items: center; }
.ig-gal-sel .select { height: var(--h-xs); font-size: var(--fs-xs); min-width: 138px; }
.ig-gal-dim { font-size: var(--fs-xs); font-weight: 700; color: var(--ink-3); margin-left: var(--sp-2); }
.ig-gal-dim:first-child { margin-left: 0; }
/* 弹窗内只留这一个滚动条:筛选条与分页条固定,图区自己滚。
   竖框 + 分组卡把单卡高度从 148px 拉到 ~386px,靠 max-height 凑高度两头不讨好
   (给少了只能看见 1.2 行,给多了吸底的分页条压住最后一行) —— 改成图区吃满剩余高度,
   分页条永远落在图区下面。openModal 把内容塞进一个 wrapper div,所以 wrapper 必须是
   .modal-body 的 flex 子项(min-height:0 才压得下去);height:100% 在 flex 项上算不出确定值。 */
.ig-gal-modal .modal-body { display: flex; flex-direction: column; overflow: hidden; }
.ig-gal-body { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* 需求三十九·续:三十五加「图库 / 资产库」双标签后,图区被 .ig-src-pane 包了一层,
   下面这套「直接子元素」规则全部失配 —— pane 是普通 div(min-height:auto 不收缩),
   .ig-gal-scroll 的 flex/overflow 失效,内容撑到 2000+px 被 .modal-body 的 hidden 裁掉,
   弹窗哪里都滚不动(手机实测,桌面同样中招)。pane 自己也要进滚动链。 */
.ig-gal-body > .ig-src-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* 上一条与 .ig-src-pane[hidden]{display:none} 特异性同阶且靠后,会把隐藏态压掉(双 pane 同显,
   实测资产库图区被挤到 138px)—— 隐藏规则同选择器加 [hidden] 提一档 */
.ig-gal-body > .ig-src-pane[hidden] { display: none; }
.ig-src-pane > .ig-gal-bar, .ig-src-pane > .ig-gal-filters, .ig-src-pane > .pager,
.ig-src-pane > [id$="Pager"] { flex: 0 0 auto; }
.ig-src-pane > .ig-gal-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 5px; }
.ig-gal-modal .pager { position: static; flex: 0 0 auto; margin-bottom: 0; }
.ig-gal-angle {
  position: absolute; top: 6px; right: 6px; padding: 1px 6px; border-radius: var(--r-full);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .55); color: var(--scrim-ink);
  font-size: 10px; font-weight: 700;
}
.ig-seed-row { display: flex; gap: var(--sp-2); }
.ig-seed-row .input { flex: 1; }
.ig-go { height: var(--h-lg); font-size: var(--fs-lg); }
.ig-res-head { display: flex; align-items: baseline; gap: var(--sp-3); margin-bottom: var(--sp-3); flex-wrap: wrap; }
.ig-filters { align-items: center; }
.ig-res-mod { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); font-weight: 700; }
.ig-res-mod .select { height: var(--h-2xs); font-size: var(--fs-xs); max-width: 200px; }
/* 左列定高:展开「负面提示词」时提示词框自己缩,整块创作台不会跟着跳一下。
   高度取右列的自然高度(模型+风格+按钮+成本),两边齐平就不用在按钮上方留一段空。
   展开区一律定高内滚(见 .igc-fold-body),所以「两栏都展开」也不会把内容顶出这个盒子
   需求三十二·1:「随机捏人」一次写进去六百多字,268px 只剩 6 行可看,提示词成了主角就得给它位置。 */
@media (min-width: 1081px) {
  .igc-main { height: 320px; }
  /* 右列:模型 + 风格两个字段挨成一组,主行动钉在底边与左列折叠行齐平。
     原来整列 space-between,左列一抬高,两个下拉之间就被撑出一段说不清的空白。 */
  .igc-side { justify-content: flex-start; }
  .igc-side .igc-go-row { margin-top: auto; }
  .igc-prompt { flex: 1 1 60px; min-height: 40px; resize: none; }
}
.ig-neg { min-height: 56px; max-height: 84px; }
@media (max-width: 1080px) {
  .igc-top { grid-template-columns: minmax(0, 1fr); }
  .igc-side { border-left: none; padding-left: 0; border-top: 1px dashed var(--line-strong); padding-top: var(--sp-3); }
  .igc-go-row { margin-top: var(--sp-2); }
}
/* 触屏上这些目标都太小:负面词条原本 42×22、参考芯片的移除键 18×18,手指点不准 */
@media (max-width: 720px) {
  .ig-neg-chip { height: 32px; padding: 0 12px; }
  .ig-slot-x { width: 26px; height: 26px; }
  .ig-slot-x .ico { width: 13px; height: 13px; }
  .ig-ratio { min-height: 40px; }
  .ig-hist-item { padding: 8px; }
  .ig-hist-clear { min-height: 34px; }
}
/* 手机上一行两张参考芯片:五张竖排会把创作台撑到 1300px 高,要滚三屏才看到生成记录 */
@media (max-width: 600px) {
  .ig-slot { flex: 1 1 calc(50% - 4px); max-width: none; }
  .ig-slot-media { width: 40px; height: 40px; }
  .ig-slot-box { min-height: 52px; }
  .ig-slots { min-height: 68px; }
}
.ig-res-title { font-size: var(--fs-lg); font-weight: 700; display: flex; align-items: center; gap: var(--sp-2); }
.ig-res-title svg { width: 15px; height: 15px; color: var(--gold); }
.ig-res-title b { font-family: var(--mono); color: var(--gold-text); }
.ig-res-run { font-style: normal; font-size: var(--fs-sm); color: var(--ok); font-weight: 700; }
.ig-res-meta { font-size: var(--fs-sm); color: var(--ink-3); }
.ig-filters { display: flex; flex-wrap: wrap; gap: var(--gap-xs); margin-bottom: var(--sp-3); }
.ig-filters .cat-chip i { font-style: normal; opacity: .7; font-family: var(--mono); }
.ig-res-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--ig-card-min), 1fr)); gap: var(--gap-sm); }
.ig-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; display: flex; flex-direction: column; transition: border-color .16s, transform .16s; }
.ig-card:hover { border-color: var(--line-strong); transform: translateY(-2px); }
/* 媒体框定高:此前每格按图片真实宽高比撑高,同一行里差到 109px,
   短图卡片的文字区被拉出一片死白 —— 比例改由角标文字说明,不再靠形状暗示 */
.ig-card-media { position: relative; height: var(--media-h); flex-shrink: 0; background: var(--surface-3); overflow: hidden; }
.ig-card-imgs { display: grid; grid-template-columns: repeat(2, 1fr); grid-auto-rows: 1fr; gap: 2px; height: 100%; background: var(--surface-sunk); }
.ig-img-cell { position: relative; min-height: 0; overflow: hidden; cursor: zoom-in; }
.ig-card-imgs .ig-img-cell:only-child { grid-column: 1 / -1; }
/* 压在图片 / 进度块上的状态角标:必须是实底语义色,
   列表里那套「语义色文字 + 12% 半透明底」放到照片上就完全读不出 */
.ig-card-flag { position: absolute; top: var(--gap-xs); left: var(--gap-xs); z-index: 3; }
.ig-card-flag .status { border: 1px solid transparent; }
.ig-card-flag .status-completed { background: var(--ok); color: var(--ok-ink); border-color: transparent; }
.ig-card-flag .status-processing { background: var(--proc); color: var(--proc-ink); border-color: transparent; }
.ig-card-flag .status-failed { background: var(--danger); color: var(--danger-ink); border-color: transparent; }
.ig-card-flag .status-queued, .ig-card-flag .status-cancelled {
  background: var(--flag-idle); color: var(--flag-idle-ink); border-color: var(--flag-idle-line);
  box-shadow: var(--elev-1);
}
.ig-card-flag .status .status-dot { background: currentColor; }
.ig-card-count {
  position: absolute; bottom: var(--gap-xs); left: var(--gap-xs); z-index: 3;
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 2px var(--sp-2);
  border-radius: var(--r-full); font-size: var(--fs-xs); font-weight: 700; font-family: var(--mono);
  background: rgba(var(--scrim-rgb), .72); color: var(--scrim-ink); border: 1px solid var(--scrim-line);
}
.ig-img-cell img { width: 100%; height: 100%; object-fit: cover; opacity: .94; transition: transform .2s, opacity .2s; }
.ig-img-cell:hover img { transform: scale(1.04); opacity: 1; }
.ig-img-view {
  position: absolute; right: 6px; bottom: 6px; width: 26px; height: 26px; border-radius: var(--r-sm);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .7); color: var(--scrim-ink);
  cursor: pointer; display: grid; place-items: center; opacity: 0; transition: opacity .15s;
}
.ig-img-view svg { width: 12px; height: 12px; }
.ig-img-cell:hover .ig-img-view { opacity: 1; }
.ig-card-progress { height: 100%; display: flex; flex-direction: column; justify-content: center; padding: 0 var(--sp-5); text-align: center; }
.ig-card-bar { height: 5px; border-radius: var(--r-full); background: rgba(var(--film), .08); overflow: hidden; margin-bottom: 10px; }
.ig-card-bar i { display: block; height: 100%; background: var(--gold-fill); transition: width .5s ease; }
.ig-card-progress span { font-size: var(--fs-sm); color: var(--ink-2); font-family: var(--mono); }
.ig-card-fail {
  height: 100%; display: flex; align-items: center; padding: 0 var(--sp-4);
  font-size: var(--fs-sm); color: var(--danger); line-height: 1.6; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ig-card-info { flex: 1 1 auto; min-height: 0; padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--gap-xs); }
.ig-card-prompt {
  font-size: var(--fs-md); line-height: 1.55; cursor: pointer;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ig-card-prompt:hover { color: var(--gold-text); }
.ig-card-meta { font-size: var(--fs-xs); color: var(--ink-3); font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ig-card-meta .dot-sep { opacity: .5; margin: 0 3px; }
/* 动作条压在封面上常显:hover 才出在手机上等于没有 */
.ig-card-acts { position: absolute; right: 6px; bottom: 6px; z-index: 2; display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.ig-ico-btn {
  width: 28px; height: 28px; display: grid; place-items: center; border-radius: var(--r-sm);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .6); color: var(--scrim-ink);
  cursor: pointer; text-decoration: none; transition: all .14s;
}
.ig-ico-btn:hover { background: rgba(var(--scrim-rgb), .9); color: var(--scrim-ink); text-decoration: none; }
.ig-ico-btn.danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
.ig-ico-btn .ico { width: 14px; height: 14px; }
/* 原生 title 要悬停近一秒才出、手机上根本没有 —— 用 ::after 做即时提示(需求三十四·7-3) */
.ig-ico-btn { position: relative; }
.ig-ico-btn[data-tip]::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 6px); left: 50%;
  transform: translateX(-50%) translateY(2px); padding: 3px 7px; border-radius: var(--r-xs);
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .1s, transform .1s; box-shadow: var(--elev-2); z-index: 6;
}
.ig-ico-btn[data-tip]:hover::after, .ig-ico-btn[data-tip]:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }
/* ⋯ 菜单:挂在 body 上,不受卡片 overflow 裁切;每一项都带文字 */
.ig-card-menu {
  position: fixed; z-index: 120; min-width: 208px; padding: 4px;
  border-radius: var(--r-md); border: 1px solid var(--line-strong); background: var(--surface);
  box-shadow: var(--elev-2);
}
.ig-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 9px; border: none;
  border-radius: var(--r-sm); background: none; color: var(--ink); font-size: var(--fs-sm);
  text-align: left; cursor: pointer;
}
.ig-menu-item:hover { background: var(--surface-hover); }
.ig-menu-item.danger { color: var(--danger); }
.ig-menu-item.danger:hover { background: rgba(var(--danger-rgb), .1); }
.ig-menu-item .ico { width: 13px; height: 13px; opacity: .75; flex: 0 0 auto; }
/* 参考来源条:一眼看出这张图是拿哪几张参考生成的 */
.ig-card-refs { display: flex; align-items: center; gap: 4px; margin-top: 7px; }
/* 参考来源:每块带「图N」角标,和服务端配方里的编号对得上,点整块看大图 */
.ig-card-ref {
  position: relative; padding: 0; border: 1px solid var(--line); border-radius: var(--r-xs);
  background: var(--bg-deep); cursor: zoom-in; overflow: hidden; line-height: 0;
}
.ig-card-ref img { display: block; width: 30px; height: 38px; object-fit: cover; }
.ig-card-ref b {
  position: absolute; left: 1px; bottom: 1px; min-width: 12px; padding: 0 2px; border-radius: 3px;
  background: rgba(var(--scrim-rgb), .78); color: var(--scrim-ink);
  font-size: 9px; font-weight: 800; line-height: 12px; text-align: center;
}
.ig-card-ref:hover { border-color: var(--gold); }
.ig-card-refs-n { font-size: var(--fs-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; margin-left: 2px; }
.ig-pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: var(--sp-2); padding: 2px; }
.ig-pick-item { position: relative; border-radius: var(--r-sm); overflow: hidden; border: 2px solid transparent; cursor: pointer; background: var(--surface-2); }
.ig-pick-item img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.ig-pick-item.sel { border-color: var(--gold); }
.ig-pick-check {
  position: absolute; top: 6px; left: 6px; width: 22px; height: 22px; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .5); background: rgba(var(--scrim-rgb), .45); color: var(--scrim-ink);
  display: grid; place-items: center; opacity: 0; transition: opacity .14s;
}
.ig-pick-check svg { width: 12px; height: 12px; }
.ig-pick-item.sel .ig-pick-check { opacity: 1; background: var(--gold); border-color: var(--gold); color: var(--gold-ink); }
.ig-pick-name {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 22px var(--sp-2) 6px; font-size: var(--fs-xs); color: var(--scrim-ink);
  background: linear-gradient(transparent, rgba(var(--scrim-rgb), .82)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ig-pick-zoom {
  position: absolute; top: 6px; right: 6px; width: 24px; height: 24px; border-radius: var(--r-sm);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .55); color: var(--scrim-ink);
  cursor: pointer; display: grid; place-items: center; opacity: 0; transition: opacity .14s;
}
.ig-pick-zoom svg { width: 12px; height: 12px; }
.ig-pick-item:hover .ig-pick-zoom { opacity: 1; }
.ig-lb-body { text-align: center; }
.ig-lb-img { max-width: 100%; max-height: 56vh; border-radius: var(--r-md); margin: 0 auto; }
.ig-lb-meta { display: flex; align-items: center; justify-content: center; gap: var(--sp-3); margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--ink-2); flex-wrap: wrap; }
.ig-lb-count { font-family: var(--mono); color: var(--gold-text); }
.ig-lb-navs { display: flex; justify-content: center; gap: var(--sp-2); margin-top: var(--sp-4); }
/* 需求三十二·3:参考图库三条竖构图(姿势 3:4 / 服装 2:3 / 人像 4:5),
   原来一律塞进 1:1 方格再 cover,等于把头顶和脚全裁掉 —— 竖框 + contain,整张必须看得见。
   只作用于图库选图器;资产库选图器仍是方格 cover 缩略图(那里图是任意比例,裁是设计如此)。 */
.ig-pick-portrait { grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }
.ig-pick-portrait .ig-pick-item img { aspect-ratio: 3 / 4; object-fit: contain; background: var(--surface); }
/* 名称原来是压在图底的渐变条 —— 竖框里它正好挡住裙摆和鞋,那恰恰是服装参考要看的部分。
   图库这一路改成图下一行,和姿势卡的标题同一个位置。 */
.ig-pick-portrait .ig-pick-item { border: 1px solid var(--line); background: var(--surface); box-shadow: var(--card-shadow); }
.ig-pick-portrait .ig-pick-item.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
.ig-pick-portrait .ig-pick-name { position: static; padding: 5px var(--sp-2) 6px; background: none; color: var(--ink-2); }
/* 需求三十二·2:姿势按「体系 + 编号」成组,一卡一姿势,卡内一排机位 ——
   点小图只换主图,点主图才选中,免得挑个动作要在五张几乎一样的卡里来回比。 */
.ig-pose-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: var(--gap-sm); padding: 2px; }
.ig-pose-card {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
  box-shadow: var(--card-shadow); cursor: pointer; overflow: hidden;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.ig-pose-card:hover { border-color: var(--line-strong); transform: translateY(-2px); box-shadow: var(--elev-2); }
.ig-pose-card.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
/* 悬停时给「点击选用」,不再把「已选中」的勾浮出来 ——
   勾是状态,悬停是动作,两者都用同一个圆形对勾就是在说谎(实测鼠标扫过一排,
   每张卡都像已经选过了)。 */
.ig-pose-use {
  position: absolute; left: var(--gap-xs); bottom: var(--gap-xs); z-index: 2;
  display: inline-flex; align-items: center; gap: 4px; padding: 3px var(--sp-2);
  border-radius: var(--r-full); border: 1px solid var(--scrim-line);
  background: rgba(var(--scrim-rgb), .78); color: var(--scrim-ink);
  font-size: var(--fs-xs); font-weight: 700; white-space: nowrap;
  opacity: 0; transform: translateY(4px); transition: opacity .14s, transform .14s;
}
.ig-pose-use .ico { width: 11px; height: 11px; }
.ig-pose-card:hover .ig-pose-use, .ig-pose-card.sel .ig-pose-use { opacity: 1; transform: none; }
.ig-pose-card.sel .ig-pose-use { display: none; }
.ig-pose-card.sel .ig-pick-check { opacity: 1; background: var(--gold); border-color: var(--gold); color: var(--gold-ink); }
/* 勾选圈挪到右下:左上角已经被姿势编号占了,两个都标在同一个位置就是互相盖 */
.ig-pose-shot .ig-pick-check { top: auto; left: auto; right: 6px; bottom: 6px; }
.ig-pose-shot { position: relative; aspect-ratio: 3 / 4; background: var(--surface); overflow: hidden; }
.ig-pose-shot img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ig-pose-code {
  position: absolute; top: 6px; left: 6px; padding: 1px 7px; border-radius: var(--r-full);
  border: 1px solid var(--scrim-line); background: rgba(var(--scrim-rgb), .72); color: var(--scrim-ink);
  font-family: var(--mono); font-size: 10px; font-weight: 800; letter-spacing: .03em;
}
.ig-pose-cap { display: flex; flex-direction: column; gap: 2px; padding: var(--gap-xs) var(--sp-2) 0; }
.ig-pose-cap b {
  font-size: var(--fs-sm); line-height: 1.45; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ig-pose-meta { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.ig-pose-meta i { font-style: normal; flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ig-pose-meta em { font-style: normal; flex: 0 0 auto; color: var(--ink-2); }
/* 定 5 列而不是 flex:1:按机位筛过之后一组只剩 1 个小图,flex 会把它拉成整行宽的大方块 */
.ig-pose-views { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-1); padding: var(--gap-xs) var(--sp-2) var(--sp-2); }
.ig-pose-view {
  min-width: 0; padding: 0; display: block; overflow: hidden; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--surface-2);
}
.ig-pose-view img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: contain; background: var(--surface); }
.ig-pose-view i { display: block; font-style: normal; font-size: 10px; line-height: 1.6; text-align: center; color: var(--ink-3); }
.ig-pose-view:hover { border-color: var(--line-strong); }
.ig-pose-view.on { border-color: var(--sel-line); background: var(--sel-fill); }
.ig-pose-view.on i { color: var(--sel-ink); }
/* 需求三十二续:交互顺滑度。三处「生硬」——选图器换页时原地干等、
   托盘换芯片时整块闪、机位小图悬停没有任何反馈 —— 都在这一组里收掉。 */
/* 翻页 / 换筛选:图区盖一层雾 + 中心转圈。雾用 --film(深色白雾、浅色墨雾),两套主题各自成立 */
.ig-gal-scroll { position: relative; }
.ig-gal-scroll.is-loading { cursor: progress; }
.ig-gal-scroll.is-loading::after {
  content: ''; position: absolute; inset: 0; z-index: 3;
  background: rgba(var(--film), .28); backdrop-filter: blur(1px);
}
.ig-gal-scroll.is-loading::before {
  content: ''; position: absolute; top: 46%; left: 50%; z-index: 4;
  width: 20px; height: 20px; margin: -10px 0 0 -10px; border-radius: 50%;
  border: 2px solid var(--line-strong); border-top-color: var(--gold);
  animation: spin .7s linear infinite;
}
.pager.is-loading { opacity: .5; pointer-events: none; }
/* 托盘里刚换上的那一格:短促落位,让「点完有反应」看得见 */
.ig-slot.is-new { animation: popIn .32s cubic-bezier(.21, 1.02, .55, 1); }
/* 机位小图:悬停抬 1px + 边框提亮;过渡压在 140ms,鼠标扫过一排也不会一片乱跳 */
.ig-pose-view { transition: border-color .14s, background-color .14s, transform .14s; }
.ig-pose-view:hover { border-color: var(--line-strong); transform: translateY(-1px); }
.ig-pose-view.on:hover { border-color: var(--sel-line); }
/* 服装 / 人像的普通卡片也给同一套抬起过渡,和姿势卡一致 */
.ig-pick-item { transition: border-color .14s, transform .14s, box-shadow .14s; }
.ig-pick-portrait .ig-pick-item:hover { transform: translateY(-2px); box-shadow: var(--elev-2); }
.ig-pick-portrait .ig-pick-item.sel:hover { box-shadow: var(--sel-ring); }

/* ---------- 23. 后台管理 ---------- */
.em-api-box, .em-rules-box {
  border: 1px solid var(--line); border-radius: var(--r-md); background: rgba(var(--film), .015);
  padding: var(--sp-4); margin-bottom: var(--sp-4);
}
.em-api-title {
  display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-4);
  font-size: var(--fs-md); font-weight: 700; letter-spacing: .04em; color: var(--gold-text);
}
.em-api-title svg { width: 15px; height: 15px; }
.em-api-title .hint { font-weight: 400; letter-spacing: 0; text-transform: none; }
.em-api-box .field:last-child, .em-rules-box .field:last-child { margin-bottom: 0; }
.em-size-tags { display: flex; flex-wrap: wrap; gap: var(--gap-xs); }
.em-size-tag {
  display: inline-flex; align-items: center; height: 28px; padding: 0 var(--sp-3); cursor: pointer; user-select: none;
  border-radius: var(--r-full); border: 1px solid var(--line); background: none;
  font-family: var(--mono); font-size: var(--fs-sm); color: var(--ink-3); transition: all .14s;
}
.em-size-tag:hover { border-color: var(--line-strong); color: var(--ink-2); }
.em-size-tag.on { background: var(--sel-soft); border-color: var(--sel-soft-line); color: var(--sel-soft-ink); }
.mc-badge { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700; padding: 2px var(--sp-2); border-radius: var(--r-full); }
.mc-ok { background: rgba(var(--ok-rgb), .14); color: var(--ok); border: 1px solid rgba(var(--ok-rgb), .4); }
.mc-fail { background: rgba(var(--danger-rgb), .12); color: var(--danger); border: 1px solid rgba(var(--danger-rgb), .4); }
.mc-unknown { background: rgba(var(--film), .06); color: var(--ink-2); border: 1px solid var(--line); }
.proto-tag { font-size: var(--fs-xs); color: var(--ink-2); }
.mc-msg {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: var(--fs-xs); color: var(--ink-3); margin-top: 3px; max-width: 260px; line-height: 1.5; white-space: normal;
}
.free-badge {
  display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); font-weight: 700; padding: 2px var(--sp-2);
  border-radius: var(--r-full); background: rgba(var(--ok-rgb), .14); border: 1px solid rgba(var(--ok-rgb), .4); color: var(--ok);
}
.free-badge svg { width: 11px; height: 11px; }
.tag-api {
  display: inline-flex; align-items: center; padding: 2px var(--sp-2); border-radius: var(--r-full); font-size: var(--fs-xs); font-weight: 700;
  background: rgba(var(--info-rgb), .14); color: var(--info); border: 1px solid rgba(var(--info-rgb), .4);
}
/* 需求三十四:模型管理页内二级切换(模型列表/供应商管理)+ 供应商徽章 + 批量导入向导 */
.subtabs { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); flex-wrap: wrap; }
.subtab {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px var(--sp-4);
  font-size: var(--fs-sm); font-weight: 600; color: var(--ink-2); cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-full); background: transparent; transition: all .15s;
}
.subtab svg { width: 13px; height: 13px; opacity: .75; }
.subtab:hover { color: var(--ink); border-color: var(--ink-3); }
.subtab.active { color: var(--gold-text); border-color: rgba(var(--accent-rgb), .55); background: rgba(var(--accent-rgb), .08); }
.tag-provider {
  display: inline-flex; align-items: center; padding: 2px var(--sp-2); border-radius: var(--r-full); font-size: var(--fs-xs); font-weight: 700;
  background: rgba(var(--accent-rgb), .12); color: var(--gold-text); border: 1px solid rgba(var(--accent-rgb), .4);
}
.imp-list { border: 1px solid var(--line); border-radius: var(--r-md); max-height: 260px; overflow-y: auto; background: var(--panel, transparent); }
.imp-item { display: flex; align-items: center; gap: 9px; padding: 7px 12px; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); cursor: pointer; }
.imp-item:last-child { border-bottom: none; }
.imp-item:hover { background: rgba(var(--accent-rgb), .05); }
.imp-item.off { opacity: .45; cursor: not-allowed; }
.imp-item .imp-id { font-family: var(--mono); font-size: var(--fs-xs); }
/* 需求三十四·3:右键菜单供应商分组头 + 模型管理类型列三大类标签 */
.ctx-head { padding: 5px 12px 3px; font-size: 11px; font-weight: 700; color: var(--ink-3); letter-spacing: .04em; cursor: default; user-select: none; }
.cls-tag {
  display: inline-flex; align-items: center; padding: 1px var(--sp-2); border-radius: var(--r-full);
  font-size: var(--fs-xs); font-weight: 700; vertical-align: 1px;
}
.cls-video { background: rgba(var(--info-rgb), .14); color: var(--info); }
.cls-img { background: rgba(var(--accent-rgb), .14); color: var(--gold-text); }
.cls-text { background: rgba(var(--ok-rgb), .14); color: var(--ok); }
/* 需求三十四·5:供应商编辑里的 API 接入点行(名称/地址/Key/眼睛/删除) */
.ep-api-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; flex-wrap: wrap; }
.ep-api-row .input { height: 32px; font-size: var(--fs-sm); }
/* 需求三十四·6/8:列表批量操作条 —— 统一复用 .ast-batchbar 浮动胶囊
   (fixed 底部居中,与风格库/资产库同款),不再在文档流里顶内容 */
.table input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--gold); cursor: pointer; }
/* 需求三十四·8:设置卡标题「图标+标题」固定为一组靠左(hint 才能稳定在最右) */
.card-title .ct-main { display: inline-flex; align-items: center; gap: 8px; }
.setting-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--sp-4); align-items: start; }
.setting-grid .card { margin-bottom: 0; }
.tier-row { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: 6px; }
.tier-row > span:first-child { min-width: 76px; font-size: var(--fs-sm); color: var(--ink-2); }
.tier-row .input { width: 110px; }
.check-row { display: flex; align-items: center; gap: var(--sp-3); padding: 7px 0; cursor: pointer; font-size: var(--fs-md); }
.check-row .mono { font-family: var(--mono); min-width: 46px; }
.check-row .hint, .tier-row .hint { margin: 0; }
.table-ops { display: flex; gap: var(--gap-xs); flex-wrap: wrap; }

/* 主题管理 */
.tm-wrap { display: flex; flex-direction: column; gap: var(--sp-4); }
.tm-header-title { display: flex; flex-direction: column; gap: 3px; }
.hdr-title { font-family: var(--display); font-size: var(--fs-xl); font-weight: 700; display: flex; align-items: center; gap: var(--sp-2); }
.hdr-title svg { color: var(--gold); }
.hdr-sub { font-size: var(--fs-sm); color: var(--ink-2); }
.tm-card, .tm-list { margin-bottom: 0; }
.tm-header { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }
.tm-active-chip { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--line-strong); }
.tm-active-label { font-size: var(--fs-xs); color: var(--ink-3); }
.tm-active-name { font-weight: 700; }
.tm-swatches { display: flex; gap: 4px; }
.tm-swatch { width: 14px; height: 14px; border-radius: 50%; display: inline-block; flex-shrink: 0; transition: transform .12s; box-shadow: 0 0 0 1px var(--line-strong); }
.tm-swatch:hover { transform: scale(1.35); }
.tm-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.tm-grid2 .card, .tm-upload-card, .tm-list { margin-bottom: 0; }
.tm-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.tm-pickers { display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.tm-pick { display: flex; align-items: center; gap: var(--gap-xs); }
.tm-pick label { font-size: var(--fs-xs); color: var(--ink-2); white-space: nowrap; }
.tm-pick input[type="color"] { width: 40px; height: 30px; padding: 2px; border-radius: var(--r-sm); border: 1px solid var(--line); background: transparent; cursor: pointer; }
.tm-hex { font-family: var(--mono); font-size: var(--fs-xs); color: var(--ink-2); min-width: 56px; }
.tm-count { font-size: var(--fs-sm); font-weight: 400; color: var(--ink-3); }
.tm-dropzone {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-md); padding: var(--sp-6);
  text-align: center; cursor: pointer; background: rgba(var(--film), .02); transition: all .18s;
}
.tm-dropzone:hover, .tm-dropzone.dragover { border-color: var(--gold); border-style: solid; background: var(--surface-hover); }
.tm-drop-icon { margin-bottom: 6px; color: var(--gold); display: flex; justify-content: center; }
.tm-drop-text { font-weight: 600; }
.tm-files { display: flex; flex-wrap: wrap; gap: var(--gap-xs); margin-top: 10px; min-height: 0; }
.tm-file {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 3px 9px; font-size: var(--fs-xs); color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-full);
}
.tm-file .icon-btn { width: 18px; height: 18px; border: none; background: none; color: var(--ink-3); }
.tm-file .icon-btn svg { width: 12px; height: 12px; }
.tm-file .icon-btn:hover { color: var(--danger); background: none; }
.tm-upload-row { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-3); }
.tm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-3); margin-top: 10px; }
.tm-item { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--surface); transition: all .18s; }
.tm-item:hover { border-color: var(--line-strong); transform: translateY(-2px); box-shadow: var(--elev-2); }
.tm-item.tm-active { border-color: var(--gold); box-shadow: var(--sel-ring); }
.tm-preview { height: 80px; position: relative; display: flex; align-items: flex-start; justify-content: space-between; padding: 10px; }
.tm-preview-swatches { display: flex; gap: 4px; }
.tm-preview-dots { position: absolute; bottom: 8px; right: var(--sp-3); display: flex; gap: 4px; }
.tm-dot { width: 6px; height: 6px; border-radius: 50%; opacity: .75; }
.tm-body { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
.tm-name { font-weight: 700; display: flex; align-items: center; gap: var(--gap-xs); margin-bottom: 2px; }
.tm-active-tag { font-size: var(--fs-xs); background: var(--ok); color: var(--ok-ink); padding: 2px var(--sp-2); border-radius: var(--r-full); font-weight: 700; border: none; }
.tm-actions { display: flex; gap: var(--gap-xs); margin-top: var(--sp-2); }

/* ---------- 24. 积分中心与成本 ---------- */
.cc-hero {
  display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-4);
  border-radius: var(--r-md); background: rgba(var(--ok-rgb), .07); border: 1px solid rgba(var(--ok-rgb), .3);
}
.cc-balance { display: flex; align-items: baseline; gap: var(--gap-xs); flex-shrink: 0; }
.cc-balance .cc-num { font-family: var(--mono); font-size: var(--fs-3xl); font-weight: 700; line-height: 1; color: var(--ok); }
.cc-balance .cc-unit { font-size: var(--fs-sm); color: var(--ink-2); }
.cc-price { flex: 1; min-width: 0; font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.7; }
.cc-tabs { margin-bottom: var(--sp-2); }
.cc-pending {
  display: inline-flex; align-items: center; justify-content: center; min-width: var(--h-2xs); height: var(--h-2xs); padding: 0 var(--gap-xs);
  border-radius: var(--r-full); background: var(--proc); color: var(--proc-ink); font-size: var(--fs-xs); font-weight: 700;
}
.cc-row { display: flex; align-items: center; gap: var(--sp-3); padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.cc-row:last-child { border-bottom: none; }
.cc-delta { font-family: var(--mono); font-weight: 700; min-width: 52px; text-align: right; }
.cc-delta.plus { color: var(--ok); }
.cc-delta.minus { color: var(--warn); }
.cc-reason { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cc-meta { color: var(--ink-3); font-size: var(--fs-xs); white-space: nowrap; }

.cost-hint {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-xs); padding: 0 var(--sp-3); white-space: nowrap;
  border-radius: var(--r-full); border: 1px solid var(--line); background: var(--surface-hover);
  color: var(--ink-2); font-family: var(--mono); font-size: var(--fs-sm); font-weight: 600;
}
.cost-hint svg { width: 12px; height: 12px; }
.cost-hint.free { border-color: rgba(var(--ok-rgb), .4); background: rgba(var(--ok-rgb), .1); color: var(--ok); }
.cost-hint.insufficient { border-color: rgba(var(--danger-rgb), .45); background: rgba(var(--danger-rgb), .1); color: var(--danger); }

/* ---------- 25. 成果查看器 ---------- */
html.viewer-open { overflow: hidden; }
.viewer-mask {
  position: fixed; inset: 0; z-index: 600; display: flex; flex-direction: column;
  background: rgba(4, 3, 2, .94); backdrop-filter: blur(8px); animation: maskIn .18s ease both; color: var(--ink);
}
.viewer-top { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5) var(--sp-2); }
.viewer-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.viewer-name, .pv-name { font-size: var(--fs-lg); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.viewer-meta { font-size: var(--fs-sm); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.viewer-count:empty { display: none; }
.viewer-count {
  font-family: var(--mono); font-size: var(--fs-sm); color: var(--ink-2); flex-shrink: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-full); padding: 4px var(--sp-3);
}
.viewer-x { width: var(--h-md); height: var(--h-md); border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer; display: grid; place-items: center; flex-shrink: 0; }
.viewer-x:hover { background: var(--surface-2); }
/* 舞台用 flex + 子项 margin:auto 居中:grid 的隐式行高由内容决定,
   图片的 max-height:100% 解析到不确定行高上等于没约束,竖图/方图会按原始尺寸渲染后被裁掉 */
.viewer-stage {
  flex: 1 1 auto; min-height: 0; display: flex; overflow: auto; padding: var(--sp-2) 88px;
}
.viewer-media, .pv-media { margin: auto; flex: 0 0 auto; max-width: 100%; max-height: 100%; /*border-radius: var(--r-md);*/ box-shadow: var(--elev-3); }
.viewer-audio { margin: auto; }
/* 需求三十四·4:图片缩放/拖动 —— transform 承担缩放与平移,舞台裁剪溢出 */
.viewer-stage { overflow: hidden; }
img.viewer-media { object-fit: contain; cursor: grab; will-change: transform; }
img.viewer-media.dragging { cursor: grabbing; }
.viewer-zoom { font-size: var(--fs-xs); color: var(--ink-2); min-width: 46px; text-align: center; font-family: var(--mono); user-select: none; }
.viewer-audio { display: flex; flex-direction: column; align-items: center; gap: var(--sp-5); color: var(--ink-2); }
.viewer-audio .ico { width: 40px; height: 40px; }
.viewer-audio audio { width: min(520px, 78vw); }
.viewer-nav {
  position: fixed; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); cursor: pointer; display: grid; place-items: center;
}
.viewer-nav:hover { background: var(--surface-3); }
.viewer-prev { left: var(--sp-5); }
.viewer-next { right: var(--sp-5); }
.viewer-foot { position: relative; display: flex; align-items: center; justify-content: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-5) var(--sp-5); flex-wrap: wrap; }
.viewer-tag { position: absolute; left: var(--sp-5); bottom: var(--sp-5); }
.pv-tag {
  display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); padding: 3px var(--sp-3);
  border-radius: var(--r-full); background: rgba(var(--ok-rgb), .12); border: 1px solid rgba(var(--ok-rgb), .35); color: var(--ok);
}
.viewer-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; justify-content: center; }
.viewer-act {
  display: inline-flex; align-items: center; gap: var(--gap-xs); height: var(--h-md); padding: 0 var(--sp-4);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font-size: var(--fs-md); cursor: pointer; text-decoration: none; transition: all .15s;
}
.viewer-act .ico { width: 15px; height: 15px; }
.viewer-act:hover { background: var(--surface-3); border-color: var(--line-strong); text-decoration: none; }
.viewer-act.primary { background: var(--gold-fill); border-color: transparent; color: var(--gold-ink); font-weight: 700; }
.viewer-act.primary:hover { background: var(--gold-fill-h); }
.viewer-act.danger { color: var(--danger); border-color: rgba(var(--danger-rgb), .4); }
.viewer-act.danger:hover { background: rgba(var(--danger-rgb), .14); }

/* ---------- 26. 占位符链接 [资产名] ---------- */
.pl-wrap { position: relative; }
.pl-wrap-dark { background: rgba(var(--film), .03); border-radius: var(--r-md); }
.pl-mirror { position: absolute; top: 0; left: 0; z-index: 2; overflow: hidden; white-space: pre-wrap; word-break: break-word; color: transparent; pointer-events: none; }
.pl-mirror .pl-token { position: relative; border-radius: 9px; padding: 2px 0; margin: 0; }
.pl-token.ok {
  color: transparent;
  background: linear-gradient(180deg, rgba(var(--accent-rgb), .3), rgba(var(--accent-rgb), .16)) #1a1511;
  box-shadow: inset 0 0 0 1px var(--line-strong), 0 1px 5px rgba(4, 3, 2, .55);
}
.pl-token.ok .pl-timg {
  position: absolute; left: .5px; top: 50%; transform: translateY(-50%);
  width: 14px; height: 14px; border-radius: 50%; object-fit: cover; background: var(--surface);
  box-shadow: 0 0 0 1px var(--line-strong);
}
.pl-token.ok .pl-tico { display: inline-flex; align-items: center; justify-content: center; color: var(--gold-soft); }
.pl-token.ok .pl-tico svg { width: 10px; height: 10px; }
.pl-token.ok .pl-tname {
  position: absolute; left: 17px; right: 2.5px; top: 50%; transform: translateY(-50%);
  font-size: var(--pl-name-fs, 13.5px); font-weight: 700; line-height: 1; letter-spacing: .02em;
  color: var(--gold-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 1px rgba(0, 0, 0, .35);
}
.pl-token.ok:not(.has-ico) .pl-tname { left: 4px; right: 4px; }
.pl-wrap.pl-caret-in .pl-token.ok { background: rgba(var(--accent-rgb), .14); box-shadow: inset 0 0 0 1px var(--line-strong); }
.pl-wrap.pl-caret-in .pl-token.ok .pl-timg, .pl-wrap.pl-caret-in .pl-token.ok .pl-tname { opacity: .12; }
.pl-token.no {
  color: transparent; background: rgba(var(--accent-rgb), .12);
  border-bottom: 1.5px dashed var(--gold); box-shadow: inset 0 0 0 1px var(--line);
}
.pl-input { position: relative; z-index: 1; background: rgba(var(--film), .03) !important; caret-color: var(--gold); }
textarea.ws-script.pl-input, textarea.textarea.pl-input { background: rgba(var(--film), .03) !important; }
.pl-tip {
  position: fixed; z-index: 9999; max-width: 320px; padding: 6px var(--sp-3); border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line-strong); color: var(--gold-text);
  font-size: var(--fs-sm); font-weight: 600; line-height: 1.45; box-shadow: var(--elev-3);
  pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ws-pl-chips .pl-chips { padding: 0; margin-top: 7px; }
.pl-chips { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-top: var(--sp-2); min-height: 26px; }
.pl-chip {
  display: inline-flex; align-items: center; gap: var(--gap-xs); padding: 4px var(--sp-3) 4px 4px; border-radius: var(--r-full);
  font-size: 12.5px; font-weight: 600; background: var(--surface-hover); border: 1px solid var(--line-strong); color: var(--gold-text);
  animation: popIn .18s ease backwards;
}
.pl-chip img { width: 26px; height: 26px; object-fit: cover; border-radius: 50%; border: 1px solid var(--line-strong); }
.pl-chip svg { width: 12px; height: 12px; }
.pl-chip-none { font-size: var(--fs-sm); color: var(--ink-3); }
.pl-hints { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-top: 7px; }
.pl-hints-label { font-size: var(--fs-xs); color: var(--ink-3); }
.pl-hint-name {
  border: 1px dashed var(--line-strong); background: var(--surface-hover); color: var(--gold-text);
  border-radius: var(--r-xs); font-size: var(--fs-sm); padding: 2px 9px; cursor: pointer; font-family: var(--mono); transition: all .14s;
}
.pl-hint-name:hover { background: var(--surface-3); border-style: solid; }

/* ---------- 27. 动效 ---------- */
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes viewIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes riseIn { from { opacity: 0; transform: translateY(12px) scale(.99); } to { opacity: 1; transform: none; } }
@keyframes popIn { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes popDown { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes maskIn { from { opacity: 0; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
/* 顶部居中的提示条:居中位移在 #toastRoot 上,条目自身只做一个小幅下落 */
@keyframes toastInC { from { opacity: 0; transform: translateY(-10px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes barUp { from { opacity: 0; transform: translateX(-50%) translateY(16px); } to { opacity: 1; transform: translateX(-50%); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { opacity: .35; } }
@keyframes toastLife { from { width: 100%; } to { width: 0; } }
@keyframes cardFlash {
  0% { box-shadow: 0 0 0 2px var(--gold), 0 0 22px rgba(var(--accent-rgb), .4); border-color: var(--gold); }
  100% { box-shadow: none; }
}
@keyframes refFlashItem {
  0% { box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(var(--accent-rgb), .45); border-color: var(--gold); }
  100% { box-shadow: none; }
}

/* 入场动画一律用 backwards:fill-mode:both 会把 to 帧的 transform 永久留在元素上,
   而任何非 none 的 transform 都会造出一个层叠上下文 —— 页头里的下拉面板(z-index:120)
   就会被压在后面的内容栏之上(29·2 资产库「更多」面板被卡片盖住的根因)。 */
.content > *:first-child { animation: viewIn .26s cubic-bezier(.22, .61, .35, 1) backwards; }
.grid > *, .stat-cards > *, .wb-grid > *, .ig-res-grid > * { animation: riseIn .3s cubic-bezier(.22, .61, .35, 1) backwards; }
.grid > *:nth-child(2), .stat-cards > *:nth-child(2), .wb-grid > *:nth-child(2), .ig-res-grid > *:nth-child(2) { animation-delay: 30ms; }
.grid > *:nth-child(3), .stat-cards > *:nth-child(3), .wb-grid > *:nth-child(3), .ig-res-grid > *:nth-child(3) { animation-delay: 60ms; }
.grid > *:nth-child(4), .stat-cards > *:nth-child(4), .wb-grid > *:nth-child(4), .ig-res-grid > *:nth-child(4) { animation-delay: 90ms; }
.grid > *:nth-child(n+5), .stat-cards > *:nth-child(n+5), .wb-grid > *:nth-child(n+5), .ig-res-grid > *:nth-child(n+5) { animation-delay: 120ms; }
.ws-main > .ws-card { animation: riseIn .28s cubic-bezier(.22, .61, .35, 1) backwards; }
.ws-card.ref-flash { animation: cardFlash .8s ease-out both; }
.ws-ref-item.ref-flash-item { animation: refFlashItem 1s ease-out both; }
/* 静默重渲染(轮询刷新)不重播入场动画 */
.no-anim .grid > *, .no-anim .stat-cards > *, .no-anim .wb-grid > *, .no-anim .ws-main > .ws-card,
.silent-render .grid > *, .silent-render .stat-cards > *, .silent-render .card, .silent-render .ws-main > .ws-card { animation: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* 30·1:短剧工作流(需求三十 · 剧本 → 分析 → 分镜 → 画风 → 下发)
   一部剧的五个阶段共用一条左栏。几何只取既有档位,颜色只读令牌 ——
   浅色模式不为它补任何一条覆盖(它翻令牌,组件自己跟着翻)。
   位置必须在「29 浅色模式」之前:回归契约把浅色段之后的内容一律当作浅色补丁。 */
.dw { display: grid; grid-template-columns: 244px minmax(0, 1fr); gap: var(--gap); align-items: start; }
.dw-rail { display: flex; flex-direction: column; gap: var(--sp-3); }
.dw-back { display: inline-flex; align-items: center; gap: var(--gap-xs); color: var(--ink-3); font-size: var(--fs-md); text-decoration: none; }
.dw-back:hover { color: var(--gold-text); }
.dw-rail-head { padding: var(--pad-card-sm); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); }
.dw-name { font-family: var(--display); font-size: var(--fs-lg); color: var(--ink); line-height: 1.3; }
.dw-sub { margin-top: var(--sp-1); font-size: var(--fs-sm); color: var(--ink-3); }
.dw-stages { display: flex; flex-direction: column; gap: 2px; }
.dw-stage { position: relative; display: grid; grid-template-columns: var(--sq-sm) 1fr auto; align-items: center; gap: var(--gap-xs);
  padding: var(--sp-2); border: 1px solid transparent; border-radius: var(--r-sm); color: var(--ink-2); text-decoration: none; transition: background .16s, border-color .16s; }
.dw-stage .ico { width: var(--sq-sm); height: var(--sq-sm); display: grid; place-items: center; color: var(--ink-3); }
.dw-stage-label { font-size: var(--fs-md); font-weight: 600; color: var(--ink); }
.dw-stage-hint { grid-column: 2 / 4; font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.35; }
.dw-stage-n { min-width: var(--h-2xs); padding: 0 var(--sp-2); height: var(--h-2xs); border-radius: var(--r-full);
  background: rgba(var(--film), .07); color: var(--ink-2); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; display: grid; place-items: center; }
.dw-stage:hover { background: var(--surface-hover); }
/* 当前阶段用弱档选中(导航语义),不抢强档金色 —— 强档留给「就是这一个」的芯片与卡片 */
.dw-stage.active { background: var(--sel-soft); border-color: var(--sel-soft-line); }
.dw-stage.active .dw-stage-label { color: var(--sel-soft-ink); }
.dw-stage.active .ico { color: var(--sel-soft-ink); }
.dw-rail-foot { display: flex; flex-direction: column; gap: var(--sp-2); }
.dw-prog { padding: var(--sp-2) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); }
.dw-prog-top { display: flex; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-prog-bar { margin-top: var(--gap-xs); height: 4px; border-radius: var(--r-full); background: rgba(var(--film), .1); overflow: hidden; }
.dw-prog-bar > i { display: block; height: 100%; border-radius: var(--r-full); background: linear-gradient(90deg, rgba(var(--proc-rgb), .6), var(--proc)); transition: width .3s ease; }
.dw-prog-err { margin-top: var(--gap-xs); font-size: var(--fs-xs); color: var(--danger); line-height: 1.4; }
.dw-balance { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-sm); color: var(--ink-3); flex-wrap: wrap; }
.dw-balance b { color: var(--gold-text); font-variant-numeric: tabular-nums; }
.dw-free { width: 100%; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-main { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.dw-main .page-head { padding: 0; }

.dw-tip { display: flex; align-items: center; gap: var(--gap-xs); padding: var(--sp-2) var(--sp-3); border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm); background: var(--surface); font-size: var(--fs-sm); color: var(--ink-2); flex-wrap: wrap; }
.dw-tip code { font-family: var(--mono); font-size: var(--fs-xs); color: var(--gold-text); }
.dw-tip.dim { opacity: .72; }

/* 列表页的剧卡 */
.dw-drama-card { display: flex; flex-direction: column; padding: 0; overflow: hidden; text-decoration: none; color: inherit; }
.dw-drama-cover { position: relative; height: var(--media-h); display: grid; place-items: center; background: var(--surface-2);
  border-bottom: 1px solid var(--line); color: var(--ink-3); }
.dw-drama-cover .ico { width: 34px; height: 34px; opacity: .5; }
.dw-drama-badge { position: absolute; left: var(--sp-2); bottom: var(--sp-2); }
.dw-drama-body { padding: var(--sp-3) var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-1); min-height: 0; }
.dw-drama-title { font-size: var(--fs-lg); font-weight: 600; color: var(--ink); }
.dw-drama-meta { font-size: var(--fs-sm); color: var(--ink-2); }
.dw-drama-meta.dim { color: var(--ink-3); font-size: var(--fs-xs); }
.dw-drama-ops { display: flex; gap: var(--gap-xs); margin-top: var(--sp-1); opacity: 0; transition: opacity .16s; }
.dw-drama-card:hover .dw-drama-ops, .dw-drama-card:focus-within .dw-drama-ops { opacity: 1; }

/* 阶段 1:剧本 */
.dw-grid2 { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: var(--gap); align-items: start; }
.dw-col { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }
.dw-script { min-height: 260px; font-family: var(--mono); font-size: var(--fs-md); line-height: 1.6; }
.dw-drop .dropzone { margin-top: var(--sp-1); }
.dw-runline { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-2); }
.dw-metric { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-sm); color: var(--ink-2); }
.dw-metric b { color: var(--gold-text); font-variant-numeric: tabular-nums; }
.dw-check { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-sm); color: var(--ink-2); cursor: pointer; }
.dw-check input { accent-color: var(--gold); }
.dw-runrow { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.dw-epick { width: auto; }
.dw-err { margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm);
  background: rgba(var(--danger-rgb), .1); color: var(--danger); font-size: var(--fs-sm); display: flex; gap: var(--gap-xs); align-items: flex-start; }
.dw-stats-row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; font-size: var(--fs-sm); color: var(--ink-2); }
.dw-stats-row .alib-count { margin-right: 2px; }
.dw-jump { display: flex; gap: var(--gap-xs); margin-top: var(--sp-3); flex-wrap: wrap; }

/* 阶段 2:设定卡 */
.dw-ent { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.dw-ent-media { position: relative; height: var(--media-h); background: var(--surface-sunk); border-bottom: 1px solid var(--line); }
.dw-ent-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dw-ent-media.has { cursor: zoom-in; }
.dw-ent-ph { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: var(--sp-1); color: var(--ink-3); }
.dw-ent-ph .ico { width: 26px; height: 26px; opacity: .55; }
.dw-ent-ph em { font-style: normal; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-ent .asset-check { position: absolute; left: var(--sp-2); top: var(--sp-2); }
.dw-ent-media .media-type-badge { position: absolute; right: var(--sp-2); bottom: var(--sp-2); }
.dw-ent-body { padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 auto; min-height: 0; }
.dw-ent-name { font-size: var(--fs-md); font-weight: 600; color: var(--ink); }
.dw-ent-profile, .dw-ent-prompt { font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.5; }
.dw-ent-prompt { color: var(--ink-2); }
.dw-ent-foot { margin-top: auto; padding-top: var(--sp-2); display: flex; align-items: center; justify-content: space-between; gap: var(--gap-xs); }
.dw-ent-count { font-size: var(--fs-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* 阶段 3:分镜 */
.dw-saveline { display: flex; align-items: center; gap: var(--sp-2); }
.dw-ws { display: grid; grid-template-columns: 152px minmax(0, 1fr); gap: var(--gap); align-items: start; }
.dw-eps { display: flex; flex-direction: column; gap: var(--sp-2); }
.dw-eps-head { display: flex; justify-content: space-between; align-items: baseline; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-eps-list { display: flex; flex-direction: column; gap: 2px; max-height: 60vh; overflow-y: auto; padding-right: 5px; }
.dw-ep { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-xs); padding: var(--sp-1) var(--sp-2);
  border: 1px solid transparent; border-radius: var(--r-xs); background: none; color: var(--ink-2); font: inherit; font-size: var(--fs-sm); text-align: left; cursor: pointer; }
.dw-ep b { font-variant-numeric: tabular-nums; color: var(--ink-3); font-weight: 600; }
.dw-ep:hover { background: var(--surface-hover); }
.dw-ep.active { background: var(--sel-soft); border-color: var(--sel-soft-line); color: var(--sel-soft-ink); }
.dw-shots { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.dw-shot { padding: var(--sp-3) var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); box-shadow: var(--card-shadow); }
.dw-shot.sel { border-color: var(--gold); box-shadow: var(--sel-ring); }
.dw-shot.is-run { border-color: rgba(var(--proc-rgb), .5); }
.dw-shot.is-bad { border-color: rgba(var(--danger-rgb), .45); }
.dw-shot-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.dw-shot-check { position: static; width: var(--sq-sm); height: var(--sq-sm); flex-shrink: 0; }
.dw-shot-idx { min-width: var(--h-xs); height: var(--h-xs); padding: 0 var(--sp-2); display: grid; place-items: center; border-radius: var(--r-xs);
  background: rgba(var(--film), .07); color: var(--gold-text); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; font-weight: 700; }
.dw-shot-scene { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-md); color: var(--ink); font-weight: 600; }
.dw-shot-dur { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-dur { width: 56px; height: var(--h-xs); padding: 0 var(--sp-2); font-size: var(--fs-sm); }
.dw-shot-spec { padding: 1px var(--sp-2); border-radius: var(--r-xs); background: rgba(var(--accent-rgb), .1);
  color: var(--gold-text); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.dw-shot-stat { margin-left: auto; display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-shot-script { margin-top: var(--sp-2); padding: var(--sp-2); border-radius: var(--r-xs); background: rgba(var(--film), .05);
  font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.55; cursor: text; }
.dw-shot-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.dw-cell { display: flex; flex-direction: column; gap: var(--gap-xs); min-width: 0; }
.dw-cell-cap { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-cell-cap .ico { color: var(--gold-text); }
.dw-cell-n { margin-left: auto; font-variant-numeric: tabular-nums; }
.dw-cell-ta { flex: 1 1 auto; min-height: 96px; font-size: var(--fs-md); line-height: 1.6; }
.dw-shot-view { align-self: flex-start; }
.dw-cast-chips { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-top: var(--sp-2); }
.dw-cast-chips .pl-chip { cursor: pointer; }
.dw-cast-ready { display: inline-flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ok); }
.dw-shot-ops { display: flex; gap: var(--gap-xs); margin-top: var(--sp-3); flex-wrap: wrap; }
.dw-shot-end { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px dashed var(--line); font-size: var(--fs-xs); color: var(--ink-3); line-height: 1.55; }
.dw-end-cap { display: inline-block; margin-right: var(--gap-xs); padding: 1px var(--sp-2); border-radius: var(--r-xs);
  background: rgba(var(--film), .07); color: var(--ink-2); font-size: var(--fs-xs); }
.dw-save { font-size: var(--fs-xs); color: var(--ink-3); }
.dw-save[data-state="pending"], .dw-save[data-state="saving"] { color: var(--proc-text); }
.dw-save[data-state="saved"] { color: var(--ok); }
.dw-save[data-state="error"] { color: var(--danger); }

/* 阶段 4:画风矩阵 */
.dw-preset-head, .dw-preset-row { display: grid; grid-template-columns: 132px minmax(0, 1fr) auto auto; gap: var(--sp-3); align-items: center; }
.dw-preset-head { padding: 0 var(--sp-2) var(--sp-2); border-bottom: 1px solid var(--line); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-preset-row { padding: var(--sp-3) var(--sp-2); border-bottom: 1px solid var(--line); }
.dw-preset-row.off { opacity: .55; }
.dw-slot { display: flex; flex-direction: column; gap: 2px; }
.dw-slot b { font-size: var(--fs-md); color: var(--ink); }
.dw-slot .tag { align-self: flex-start; }
.dw-preset-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dw-preset-text { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.55; }
.dw-preset-meta { display: flex; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.dw-warn-long { font-style: normal; color: var(--warn); display: inline-flex; align-items: center; gap: 3px; }
.dw-preset-neg { color: var(--danger); }
.dw-switch { display: inline-flex; align-items: center; }
.dw-switch input { accent-color: var(--gold); width: var(--h-sm); height: var(--h-sm); }

/* 组装预览 */
.dw-compose { display: flex; flex-direction: column; gap: var(--sp-3); }
.dw-compose-cap { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-sm); color: var(--ink-2); flex-wrap: wrap; }
.dw-compose-tips { width: 100%; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-miss { display: inline-flex; align-items: center; gap: 3px; color: var(--warn); font-size: var(--fs-xs); }
.dw-compose-item { padding: var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2); display: flex; flex-direction: column; gap: var(--sp-2); }
.dw-compose-name { font-size: var(--fs-md); font-weight: 600; color: var(--gold-text); }
.dw-compose-base { font-size: var(--fs-sm); color: var(--ink); white-space: pre-wrap; line-height: 1.55; }
.dw-compose-plus { font-size: var(--fs-sm); color: var(--ink-3); white-space: pre-wrap; line-height: 1.55;
  padding-left: var(--sp-3); border-left: 2px solid rgba(var(--accent-rgb), .35); }
.dw-compose-ta { min-height: 180px; font-size: var(--fs-md); line-height: 1.6; }
.dw-compose-neg { font-size: var(--fs-xs); color: var(--danger); }

/* 阶段 5:下发 */
.dw-nums { margin-bottom: var(--sp-2); }
.dw-batch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr)); gap: var(--sp-2); }
.dw-batch { display: flex; align-items: center; gap: var(--sp-2); justify-content: flex-start; height: auto; padding: var(--sp-2) var(--sp-3); text-align: left; }
.dw-batch span { display: flex; flex-direction: column; gap: 1px; }
.dw-batch em { font-style: normal; font-size: var(--fs-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* 填充式布局:左栏与主区各自滚动(与资产库 / AI 生图同一机制) */
body.page-fill .dw { flex: 1 1 auto; min-height: 0; align-items: stretch; }
body.page-fill .dw-rail { position: static; min-height: 0; overflow-y: auto; padding-right: 5px; }
body.page-fill .dw-main { min-height: 0; overflow-y: auto; padding-right: 5px; }
body.page-fill .dw-ws { flex: 1 1 auto; min-height: 0; align-items: stretch; }
body.page-fill .dw-eps-list { max-height: none; flex: 1 1 auto; min-height: 0; }
body.page-fill .dw-shots { min-height: 0; overflow-y: auto; padding-right: 5px; }

/* 阶段就绪圆点:ok 绿 / part 进行中 / todo 灰。只换色相,不换几何 */
.dw-stage-dot { display: inline-block; width: 6px; height: 6px; margin-left: var(--gap-xs); border-radius: var(--r-full);
  background: var(--ink-3); opacity: .45; vertical-align: middle; }
.dw-stage[data-flag="ok"] .dw-stage-dot { background: var(--ok); opacity: 1; }
.dw-stage[data-flag="part"] .dw-stage-dot { background: var(--proc); opacity: 1; }
.dw-rail-head .dw-sub.dim { color: var(--ink-3); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }

/* 出片规格:换算结果一行读出来,免得点下发才发现尺寸不对 */
.dw-spec-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.dw-spec-row { min-width: 0; }
.dw-spec-row > .field { flex: 1 1 44%; min-width: 0; margin-bottom: var(--sp-3); }
.dw-spec-hint, .dw-spec-line { display: flex; align-items: center; gap: var(--gap-xs); margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); border: 1px dashed var(--line-strong); border-radius: var(--r-sm);
  background: rgba(var(--film), .04); font-size: var(--fs-xs); color: var(--ink-2); flex-wrap: wrap; }
.dw-spec-hint b, .dw-spec-line b { color: var(--gold-text); font-variant-numeric: tabular-nums; }
.dw-spec-line { margin-top: 0; }
.dw-spec-line .btn { margin-left: auto; }

/* 分镜参考图:手动挂在前面,自动角色定稿图跟在后面 */
.dw-refs { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-top: var(--sp-2);
  padding-top: var(--sp-2); border-top: 1px dashed var(--line); }
.dw-refs-cap { display: inline-flex; align-items: center; gap: 3px; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-ref-chip { position: relative; width: var(--sq-md); height: var(--sq-md); border-radius: var(--r-xs); overflow: hidden;
  border: 1px solid var(--line-strong); cursor: zoom-in; flex-shrink: 0; }
.dw-ref-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dw-ref-chip b { position: absolute; top: 0; right: 0; width: 13px; height: 13px; display: grid; place-items: center;
  border-bottom-left-radius: var(--r-xs); background: var(--flag-idle); color: var(--flag-idle-ink);
  font-size: 10px; font-weight: 700; line-height: 1; cursor: pointer; }
.dw-ref-chip b:hover { background: var(--danger); color: var(--danger-ink); }
.dw-refs-auto { font-size: var(--fs-xs); }
.dw-refs-cap-n { font-size: var(--fs-xs); color: var(--ink-3); }

/* 关联图片缩略条 + 成果缩略 + 地域选择(需求七) */
.dw-refs-cap b { color: var(--gold-text); font-variant-numeric: tabular-nums; }
.dw-refs .btn { height: var(--h-xs); }
.dw-ref-chip:hover { border-color: var(--gold); }
.dw-ref-chip:hover b { opacity: 1; }
.dw-ref-chip b { opacity: .78; transition: opacity .15s; }
.dw-results { display: flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; margin-top: var(--sp-2); }
.dw-res-thumb { position: relative; width: 46px; height: 34px; border-radius: var(--r-xs); overflow: hidden;
  border: 1px solid var(--line-strong); cursor: zoom-in; flex-shrink: 0; background: var(--surface-sunk); }
.dw-res-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dw-res-thumb i { position: absolute; inset: 0; display: grid; place-items: center; color: var(--scrim-ink);
  background: rgba(var(--scrim-rgb), .26); }
.dw-res-thumb i svg { width: 13px; height: 13px; }
.dw-res-name { max-width: 220px; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-cell-solo { margin-top: var(--sp-3); }
.dw-cell-tip { margin-left: auto; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-region { display: inline-flex; align-items: center; gap: var(--gap-xs); }
.dw-region .select { width: auto; min-width: 110px; height: var(--h-sm); }
.cat-chip em { font-style: normal; font-size: var(--fs-xs); color: var(--gold-text); margin-left: 3px; }

/* 进度:镜卡上一条细条 + 任务表里的迷你条(需求:图片/视频生成都要看得见进度) */
.dw-mini-bar { display: inline-block; width: 54px; height: 4px; border-radius: var(--r-full);
  background: rgba(var(--film), .12); overflow: hidden; vertical-align: middle; }
.dw-mini-bar.wide { width: 76px; }
.dw-mini-bar > i { display: block; height: 100%; border-radius: var(--r-full);
  background: linear-gradient(90deg, rgba(var(--proc-rgb), .55), var(--proc)); transition: width .3s ease; }
.dw-progcell { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-progcell em { font-style: normal; font-variant-numeric: tabular-nums; }
.dw-progcell em.ok { color: var(--ok); }
.dw-refs-tags { margin-left: var(--sp-2); font-style: normal; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-ref-chip { width: 40px; height: 40px; }
.dw-ref-chip b { width: 14px; height: 14px; }

.dw-ep-prog { font-style: normal; font-size: var(--fs-xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.dw-ep.active .dw-ep-prog { color: var(--sel-soft-ink); }
.dw-shot-filters { margin-top: 0; }
.dw-shot-filters .cat-chips { margin-bottom: 0; }

/* 关联标记:全站唯一一处展示「下发时会附加什么」。芯片可点跳设定卡,带定稿图的打「图」标 */
.dw-anchors { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-xs) var(--sp-3);
  margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm); background: rgba(var(--film), .04); border: 1px dashed var(--line-strong); }
.dw-anchor { display: inline-flex; align-items: center; gap: var(--gap-xs); flex-wrap: wrap; font-size: var(--fs-xs); color: var(--ink-2); }
.dw-anchor + .dw-anchor { border-left: 1px solid var(--line); padding-left: var(--sp-3); }
.dw-anchor b { padding: 0 var(--sp-2); border-radius: var(--r-xs); background: rgba(var(--accent-rgb), .1); color: var(--gold-text); font-weight: 600; }
.dw-anchor em { font-style: normal; color: var(--ink-3); }
.dw-anchor .pl-chip { cursor: pointer; }
.dw-chip-img { border-color: rgba(var(--accent-rgb), .5); }
.dw-anchor-extra { font-style: normal; font-size: var(--fs-xs); color: var(--ink-3); }
.dw-anchor-tip { margin-left: auto; display: inline-flex; align-items: center; gap: 3px; font-size: var(--fs-xs); color: var(--ink-3); }

/* 关联体检 / 替换图片(需求:修复异常 · 替换不想要的图) */
.dw-badge-warn { min-width: var(--h-2xs); height: var(--h-2xs); margin-left: var(--gap-xs); padding: 0 var(--sp-2);
  display: inline-grid; place-items: center; border-radius: var(--r-full); background: rgba(var(--danger-rgb), .16);
  color: var(--danger); font-size: var(--fs-xs); font-weight: 700; font-variant-numeric: tabular-nums; }
.dw-repair { display: flex; flex-direction: column; gap: var(--sp-3); }
.dw-repair-sect { padding: var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2); }
.dw-repair-title { display: flex; align-items: center; gap: var(--gap-xs); font-size: var(--fs-md); font-weight: 600; color: var(--ink); margin-bottom: var(--sp-1); }
.dw-repair-title em { font-style: normal; padding: 0 var(--sp-2); border-radius: var(--r-full); background: rgba(var(--accent-rgb), .12);
  color: var(--gold-text); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.dw-repair-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  padding: 3px 0; border-top: 1px dashed var(--line); font-size: var(--fs-sm); color: var(--ink-2); }
.dw-repair-row span { min-width: 0; word-break: break-all; }
.dw-repair-row em { font-style: normal; flex-shrink: 0; color: var(--ink-3); font-size: var(--fs-xs); }
.dw-repair-sect.warn { border-color: rgba(var(--warn-rgb), .35); }
.dw-repair-pick { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); padding-top: var(--sp-2);
  border-top: 1px dashed var(--line); font-size: var(--fs-xs); color: var(--ink-3); }
.dw-repair-pick .select { width: auto; min-width: 220px; height: var(--h-sm); }
.dw-replace { display: flex; flex-direction: column; gap: var(--sp-3); }
.dw-replace-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.dw-ent-replace { position: absolute; right: var(--sp-2); top: var(--sp-2); width: var(--sq-sm); height: var(--sq-sm);
  display: grid; place-items: center; border-radius: var(--r-xs); cursor: pointer; opacity: 0; transition: opacity .15s;
  background: var(--flag-idle); color: var(--flag-idle-ink); border: 1px solid var(--flag-idle-line); }
.dw-ent-media:hover .dw-ent-replace { opacity: 1; }
.dw-ent-replace svg { width: 13px; height: 13px; }

/* ---------- 28. 响应式 ---------- */
/* 超宽屏继续吃满宽度,只留呼吸边距(27·3) */
@media (min-width: 2100px) {
  :root { --content-w: min(2320px, 100%); }
}
@media (max-width: 1360px) {
  .top-link span { display: none; }
  .top-link { padding: 7px var(--sp-2); }
  .top-link.active::before { left: var(--sp-2); right: var(--sp-2); }
}
@media (max-width: 1180px) {
  .cmdk-t-kbd { display: none; }
  .ws-card-grid { grid-template-columns: 252px minmax(0, 1fr); }
  .ctx-tab span { display: none; }
}
@media (max-width: 1080px) {
  .top-nav { display: none; }
  .nav-more { display: block; }
  .ws-card-grid { grid-template-columns: 1fr; }
  .ws-shot-editor { order: -1; }
  .ws-shot-params { border-right: 0; border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ws-body { flex-direction: column; overflow-y: auto; }
  /* 26·4:窄屏下工作台纵向堆叠,.ws-body 成为唯一滚动容器,分镜列不再自己滚(双滚动条) */
  .ws-main { overflow: visible; }
  .ws-left { width: 100%; max-height: 240px; }
  .ws-left.folded { width: 100%; height: 44px; max-height: 44px; }
  .ws-left-open-label { writing-mode: horizontal-tb; }
  .ws-left-open { flex-direction: row; justify-content: center; padding: var(--sp-2) 0; }
  .ast-layout { flex-direction: column; }
  /* 31:工作流左栏、剧本两栏、分镜双提示词栏在窄屏一律纵向堆叠 */
  .dw, .dw-grid2, .dw-ws, .dw-shot-grid { grid-template-columns: minmax(0, 1fr); }
  .dw-preset-head, .dw-preset-row { grid-template-columns: 92px minmax(0, 1fr) auto auto; }
  .dw-eps-list { max-height: 168px; }
  .ast-side { width: 100%; }
  .tm-grid2 { grid-template-columns: 1fr; }
  .dash-hero { flex-wrap: wrap; }
  .dash-hero .dh-storage { width: 100%; }
}
@media (max-width: 880px) {
    .content { padding: var(--sp-4); }
  .topbar { padding: 0 var(--sp-4); gap: var(--sp-3); }
  .brand-sub { display: none; }
  .stat-cards { grid-template-columns: repeat(2, 1fr); }
  .auth-stage { max-width: 460px; }
  .auth-poster { display: none; }
  .auth-card { width: 100%; border-left: none; }
  .page-head { align-items: flex-start; }
}
@media (max-width: 720px) {
  .tu-name { display: none; }
  .wb-toolbar, .ws-bar { padding: var(--sp-2) var(--sp-4); }
  .wb-canvas, .ws-body { padding-left: var(--sp-4); padding-right: var(--sp-4); }
}
/* 手机顶栏:品牌文字 + 搜索 + 积分 + 导航⋯ + 铃铛 + 主题 + 头像 一行放不下,
   flex 收缩后 nowrap 的文字直接互相压在彼此上面(390px 实测重叠 38px)。
   窄屏一律让位:品牌只留 logo、导航只留汉堡图标、积分去掉余量、头像去掉下拉箭头。 */
@media (max-width: 560px) {
  .topbar { padding: 0 12px; gap: var(--gap-xs); }
  .topbar-left { gap: var(--gap-xs); }
  .topbar-right { gap: var(--gap-xs); }
  .brand-text { display: none; }
  .nav-more-btn { padding: 7px 9px; }
  .nav-more-btn span { display: none; }
  .credit-chip { padding: 0 8px; }
  .top-user-btn .tu-caret { display: none; }
  .page-head .page-actions { flex-wrap: wrap; }
}

/* ---------- 28·1 需求三十九:移动端适配 ---------- */
/* 触屏(手机 / 平板,无 hover)最大的坑:一批操作钮是「悬停才显形」的,
   触屏上 hover 不触发,控件永远看不见也点不到 —— 一律常显。
   这批控件本来就是为触屏设计的「点一下就动作」的入口,常显不添乱。 */
@media (hover: none) {
  .proj-ops, .wb-ep-ops, .dw-drama-ops, .dw-ent-replace,
  .ws-ref-zoom, .ig-img-view, .ig-pick-zoom,
  .asset-check, .ig-pick-item .ig-pick-check, .ig-pose-card .ig-pose-use {
    opacity: 1; transform: none;
  }
  /* 例外:.proj-ops 桌面上是绝对定位悬浮在项目码芯片上的(hover 换装),
     触屏常显会永久盖住芯片 —— 改回文档流,作为卡片底部一行操作 */
  .proj-ops { position: static; justify-content: flex-end; margin-top: var(--sp-1); }
  /* 选图弹窗里的「悬停机位小图预览」提示是纯桌面手势,触屏上是死文字 */
  .ig-gal-tip { display: none; }
}

/* 手机宽度(≤600px):真机可用性 —— 输入 16px 防 iOS 聚焦自动放大、
   弹窗近全屏、浮条限宽避开 Home 条、触控目标抬高到 32px。 */
@media (max-width: 600px) {
  /* iOS Safari:输入控件字号 < 16px 时聚焦会整页放大,回来还得手动缩回 */
  .input, .select, .textarea, .cmdk-input { font-size: 16px; }

  /* 顶栏降一档(64 → 56),给内容让高度;toast/浮层都以 --topbar-h 定位,自动跟随 */
  :root { --topbar-h: 56px; }

  /* 弹窗近全屏:内白与圆角收紧,底部按钮拉满宽,单手好按 */
  .modal-mask { padding: 10px; }
  .modal, .modal-sm, .modal-md, .modal-lg, .modal-xl { max-width: 100%; }
  .modal-head { padding: var(--sp-3) var(--sp-4); }
  .modal-body { padding: var(--sp-4); }
  .modal-foot {
    padding: var(--sp-3) var(--sp-4);
    padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  }
  .modal-foot .btn, .modal-foot .btn-primary { flex: 1 1 auto; min-width: 0; }

  /* 批量浮条:fixed + left:50% 下盒宽只会取视口左半边(fit-content 顺着 containing block 算),
     max-width 再不设,宽内容要么溢出要么提前折行 —— 显式 max-content + 上限让它单行居中、
     超宽才折;wb 款保留 96px 抬升(避开工作台底栏),ast 款抬离 Home 条 */
  .ast-batchbar, .wb-batchbar {
    width: max-content; max-width: calc(100vw - 24px);
    flex-wrap: wrap; justify-content: center;
  }
  .ast-batchbar { bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  .wb-batchbar { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
  /* 浮条出现时「返回顶部」抬高一行,不再互相压住 */
  body:has(.ast-batchbar) .to-top, body:has(.wb-batchbar) .to-top {
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  }
  .to-top { right: 12px; }

  /* 弹层限宽:通知面板在 320~360px 屏上不再顶出左边界 */
  .notif-panel { max-width: calc(100vw - 24px); }

  /* 触控目标:28px 的筛选芯片 / 分页钮提到 32px,手指点得准 */
  .cat-chip, .pg-btn { height: 32px; }

  /* 表格行内白收紧:窄屏上横向滚动的表少滚一屏 */
  .table th { padding: var(--head-py) var(--sp-3); }
  .table td { padding: var(--row-py) var(--sp-3); }

  /* 登录卡内白收紧 */
  .auth-card { padding: 28px var(--sp-5); }

  /* 规格行 44% 两列在 320~390px 挤成一条缝,改单列 */
  .dw-spec-row > .field { flex: 1 1 100%; }

  /* 画风预设表:四列(槽位/内容/开关/操作)手机上改三行,
     列头描述的是旧列位,一并藏掉 */
  .dw-preset-head { display: none; }
  .dw-preset-row { grid-template-columns: minmax(0, 1fr) auto; }
  .dw-preset-row > .dw-slot { grid-column: 1; grid-row: 1; min-width: 0; }
  .dw-preset-row > .dw-switch { grid-column: 2; grid-row: 1; justify-self: end; }
  .dw-preset-row > .dw-preset-body { grid-column: 1 / -1; grid-row: 2; }
  .dw-preset-row > .table-ops { grid-column: 1 / -1; grid-row: 3; }

  /* 生图结果卡:一列只剩半屏宽,图太小;降到 150px 最小宽出两列
     (ui.js 的 gridPageSize 读同一个 CSS 变量算列数,自动保持一致) */
  :root { --ig-card-min: 150px; }

  /* 仪表盘英雄区收紧;操作行独占一行 —— dh-main 是 flex:1 1 0%(基准 0),
     操作钮 flex-shrink:0,手机宽度下主文案列会被压到只剩几像素(实测 28px 竖排),
     让操作行 basis 100% 换行,问候语才有位置 */
  .dash-hero { padding: var(--sp-4); gap: var(--sp-3); }
  .dash-hero .dh-actions { flex: 1 1 100%; }
  .dash-hero .dh-title { font-size: var(--fs-xl); }
  .dash-hero .dh-storage { width: 100%; }

  /* 选图弹窗:筛选芯片行太多时把图区压成一条缝(手机实测只剩 138px 高),限高两行自己滚 */
  .ig-gal-modal .ig-gal-filters { max-height: 96px; overflow-y: auto; }

  /* 查看器:翻页钮收小靠边浮在图上,舞台两侧不再各留 88px(手机上图只剩 214px 宽);
     分类角标改随流排,不再压住换行后的操作按钮 */
  .viewer-top { padding: var(--sp-3) var(--sp-4) var(--sp-1); }
  .viewer-stage { padding: var(--sp-2) var(--sp-3); }
  .viewer-foot { padding: var(--sp-2) var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px)); }
  .viewer-nav { width: 38px; height: 38px; }
  .viewer-prev { left: 8px; }
  .viewer-next { right: 8px; }
  .viewer-tag { position: static; margin-right: var(--sp-2); }
}

/* ---------- 29. 浅色模式(html[data-scheme="light"]) ---------- */
html[data-scheme="light"] { color-scheme: light; }
/* 浅色主题「青白 · 疏朗」(需求三十再迭代):
   冷雾画布 + 纯白卡片浮起 + 更亮的青蓝强调 + 拉开一档的留白与行高。
   全部走令牌取值,组件规则零改动;深色「鎏金胶片」逐像素不受影响。 */
html[data-scheme="light"] {
  /* 画布与卡片必须差出一档,否则整页就是一张铺满发丝线的白纸 */
  --bg: #f4f8fc;
  --bg-deep: #eaf1f8;
  --surface: #ffffff;
  --surface-2: #f6fafd;
  --surface-3: #e9f1f8;
  --surface-sunk: #dfe9f3;
  --surface-hover: rgba(42, 118, 186, .07);
  --line: rgba(23, 43, 66, .09);
  --line-strong: rgba(23, 43, 66, .18);
  --line-faint: rgba(23, 43, 66, .05);
  /* 浅底上的「薄雾」要换成墨色,否则 rgba(白,.03) 在白卡上等于不存在 */
  --film: 23, 40, 62;
  /* 压在图片上的浮层:底色翻冷墨,字/边保持白系(组件各自的浓度不再被统一压平) */
  --scrim-rgb: 18, 32, 48;
  --scrim-ink: #ffffff;
  --scrim-line: rgba(255, 255, 255, .3);
  --scrim-accent: #ffffff;
  --ink: #16202e;
  --ink-2: #4a5b6e;
  --ink-3: #5f7183;

  /* 强调色:青蓝(比靛蓝更亮更透),实心只留给主行动按钮 */
  --accent-rgb: 42, 118, 186;
  --accent-hi-rgb: 143, 189, 227;
  --accent-deep-rgb: 29, 92, 147;
  --gold: #2a76ba;          /* 图标 / 描边 / 聚焦:白底 4.8:1 */
  --gold-soft: #8fbde3;
  --gold-deep: #1d5c93;
  --gold-fill: #2a76ba;     /* 主行动实心底,白字 4.8:1 */
  --gold-fill-h: #3687cc;
  --gold-fill-a: #1d5c93;
  --gold-text: #1d5c93;     /* 小号强调文字:白底 6.9:1 */
  --gold-ink: #ffffff;
  /* 浅色下「强 / 弱」两级选中态收敛成同一种淡蓝 —— 实心只留给主行动按钮 */
  --sel-fill: #e7f2fb;
  --sel-ink: #1a5588;
  --sel-line: #c2dcf2;
  --sel-soft: #e7f2fb;
  --sel-soft-ink: #1a5588;
  --sel-soft-line: #c2dcf2;
  --ring: 0 0 0 3px rgba(var(--accent-rgb), .18);   /* 白底上聚焦环要更实一点 */
  --ok-ink: #ffffff;
  --warn-ink: #ffffff;
  --danger-ink: #ffffff;
  --ok: #177a52;
  --warn: #a85a12;
  --danger: #c53a32;
  --info: #1d5c93;          /* 并入主色族的深一档:11px 小标签在白底淡蓝上也要过 AA */
  /* 底纹三元组取「中间调」而非 ink 本身:直接用 --ok 的深绿做 14% 底,底色会重到
     把 11px 粗体字压到 4.5:1 以下(4.46)。这两档是量出来的,不是随手挑的。 */
  --ok-rgb: 46, 158, 114;
  --warn-rgb: 190, 112, 26;
  --danger-rgb: 222, 96, 88;
  --info-rgb: 42, 118, 186;
  --proc: var(--gold-fill);
  --proc-ink: var(--gold-ink);
  --proc-text: var(--gold-text);
  --proc-soft: rgba(var(--accent-rgb), .12);
  /* 占位块上的角标:浅底 + 墨字 + 一圈影子,不再是一块深色主题残留的深底浮层 */
  --flag-idle: #ffffff;
  --flag-idle-ink: var(--ink-2);
  --flag-idle-line: var(--line-strong);
  --grad-gold: linear-gradient(115deg, #7fb6e2 8%, #2a76ba 52%, #17456f 96%);

  /* 空间:卡片间距、卡内白、表格行高、页头字号与上方留白各放宽一档 */
  --r-xs: 7px; --r-sm: 9px; --r-md: 14px; --r-lg: 20px;
  --gap: 20px; --gap-sm: 16px;
  --pad-card: 24px; --pad-card-sm: 16px 22px;
  --row-py: 14px; --head-py: 12px;
  --pad-page: 32px;
  --fs-page-title: 22px;

  /* 层级:靠影子浮起,不靠描边圈地 */
  --card-shadow: 0 1px 2px rgba(23, 43, 66, .04), 0 10px 24px rgba(23, 43, 66, .07);
  --elev-1: 0 1px 2px rgba(23, 43, 66, .05);
  --elev-2: 0 2px 6px rgba(23, 43, 66, .06), 0 12px 28px rgba(23, 43, 66, .10);
  --elev-3: 0 20px 48px rgba(23, 43, 66, .16), 0 3px 8px rgba(23, 43, 66, .06);
  --glow: 0 6px 20px rgba(42, 118, 186, .16);
}

html[data-scheme="light"], html[data-scheme="light"] body { background: #f4f8fc; }
html[data-scheme="light"] body::before {
  background:
    radial-gradient(1300px 640px at 10% -10%, rgba(42, 118, 186, .06), transparent 60%),
    radial-gradient(1000px 560px at 94% 0%, rgba(143, 189, 227, .12), transparent 58%),
    radial-gradient(1200px 760px at 50% 118%, rgba(120, 190, 170, .05), transparent 62%),
    #f4f8fc;
}
html[data-scheme="light"] body::after { opacity: .012; }
html[data-scheme="light"] .bg-orb-1 { background: radial-gradient(circle, rgba(42, 118, 186, .08), transparent 68%); }
html[data-scheme="light"] .bg-orb-2 { background: radial-gradient(circle, rgba(29, 92, 147, .05), transparent 66%); }
html[data-scheme="light"] .bg-orb-3 { background: radial-gradient(circle, rgba(42, 157, 108, .045), transparent 66%); }
html[data-scheme="light"] .bg-aurora::after { background: radial-gradient(120% 92% at 50% 6%, transparent 62%, rgba(23, 43, 66, .04) 100%); }
html[data-scheme="light"] ::-webkit-scrollbar-thumb { background: #c4d2e0; border-color: #f4f8fc; }
html[data-scheme="light"] ::-webkit-scrollbar-thumb:hover { background: #a3b7ca; }
html[data-scheme="light"] ::selection { background: rgba(143, 189, 227, .55); color: #12202f; }

html[data-scheme="light"] .topbar { background: rgba(255, 255, 255, .9); }
html[data-scheme="light"] .topbar::before { background: linear-gradient(90deg, transparent, rgba(42, 118, 186, .26) 18%, rgba(143, 189, 227, .4) 50%, transparent 82%); }
html[data-scheme="light"] .wb-toolbar, html[data-scheme="light"] .ws-bar, html[data-scheme="light"] .wb-ai { background: #fbfdff; }
html[data-scheme="light"] .ws { background: #eef4fa; }
html[data-scheme="light"] .ws-card-summary { background: transparent; }

/* 组件底色一律由令牌决定(`--surface*` / `rgba(var(--film), a)` / `rgba(var(--accent*-rgb), a)`),
   这里不逐条覆盖组件 —— 「属性 + 类」的权重高于 `.btn-primary`、`.cat-chip.on`、`.wb-tbtn.active`
   这类状态规则,整条覆盖会把主按钮填充和选中态一起压白(29·1 的根因)。
   下面只剩三类必要覆盖:压在图片上的浮层、语义色在浅底上的浓度补偿、以及深色专属的实色。 */
html[data-scheme="light"] .credit-chip { background: rgba(27, 122, 80, .09); }

/* 压在缩略图 / 视频上的浮层不再逐条覆盖:底色 --scrim-rgb、字色 --scrim-ink、
   描边 --scrim-line、浮层上的强调色 --scrim-accent 四个令牌在浅色段一次性翻过来,
   组件规则自己读它们。原先那 13 个选择器的白字补丁,漏一个就是一个读不出来的角标
   (`.ws-ref-tag` 就被漏成了深蓝字压深底,对比 0.55:1)。 */
html[data-scheme="light"] .media-thumb, html[data-scheme="light"] .media-thumb-empty,
html[data-scheme="light"] .ws-ref-item img, html[data-scheme="light"] .ws-clip img,
html[data-scheme="light"] .ws-clip video, html[data-scheme="light"] .ws-rec-cover,
html[data-scheme="light"] .ig-img-cell img, html[data-scheme="light"] .preview-media { background: var(--surface-3); }

html[data-scheme="light"] .modal-mask { background: rgba(18, 32, 48, .34); }
html[data-scheme="light"] .cmdk-mask { background: rgba(18, 32, 48, .28); }
/* 命令面板底部条在深色里是「比表面更黑」,浅色下要换成「比表面更灰」 */
html[data-scheme="light"] .cmdk-foot { background: var(--surface-2); }
/* [占位符] 令牌高亮:深色是金箔,浅色换成黛蓝底 + 白字(实心块,和「已链接」语义一致) */
html[data-scheme="light"] .pl-token.ok { background: linear-gradient(180deg, rgba(42, 118, 186, .95), rgba(23, 69, 111, .95)) #2a76ba; box-shadow: inset 0 0 0 1px rgba(23, 69, 111, .55); }
html[data-scheme="light"] .pl-token.ok .pl-tname { color: #ffffff; text-shadow: none; }
html[data-scheme="light"] .pl-token.ok .pl-tico { color: #d5e7f7; }

html[data-scheme="light"] .viewer-mask { background: rgba(14, 22, 32, .92); }
/* 旧的「语义色浓度补偿」(浅色给 .status-completed / .ws-log-state.ok 单独写 #136c47)已删:
   那是浅色 --ok 还很亮的年代留下的,现在 --ok 本身就是深绿。更要命的是它的权重 (0,2,1)
   压过 .ig-card-flag .status-completed (0,2,0) —— 深绿字压在深绿实底角标上,实测 1.21:1,
   等于角标上的字不存在。淡底配深字要调 --ok-rgb,不是给组件补一条更高权重的规则。 */
html[data-scheme="light"] .auth-poster {
  background: radial-gradient(130% 90% at 18% -4%, rgba(42, 118, 186, .14), transparent 58%), linear-gradient(160deg, #ffffff, #e8f1f9);
}
html[data-scheme="light"] .auth-poster .ap-title { background: linear-gradient(115deg, #7fb6e2, #17456f); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
html[data-scheme="light"] .brand-name, html[data-scheme="light"] .auth-title, html[data-scheme="light"] .cmdk-mark {
  background: linear-gradient(115deg, #5e9bd0 8%, #2a76ba 52%, #17456f 96%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

/* ---------- 30. 沉浸模式 ---------- */
body.immersive .content > * { max-width: none; margin: 0; }
