/* ============================================================
   设计令牌：唯一来源（原分散在 8 处的顶层 :root 已合并到此）。
   新增/修改全局颜色、尺寸、圆角等变量都加在这里。
   断点专属覆盖仍放各自 @media 内的 :root。
   ============================================================ */
:root {
  --bg: #f4f5f7;
  --panel: #ffffff;
  --text: #101828;
  --muted: #667085;
  --border: #e3e8f1;
  --accent: #2f6db7;
  --accent-strong: #255a9c;
  --blue: #2563a7;
  --danger: #b42318;
  --warning: #a15c07;
  --ok: #13795b;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 12px 30px rgba(16, 24, 40, 0.05);
  --ease-ui: cubic-bezier(0.22, 0.82, 0.22, 1);
  --motion-fast: 140ms;
  --motion-base: 220ms;
  --motion-slow: 360ms;
  --ui-density: 0.8;
  --font-ui: var(--scale-font-body);
  --font-label: var(--scale-font-label);
  --font-title: var(--scale-font-title);
  --font-section-title: var(--scale-font-section);
  --sidebar-expanded: 168px;
  --sidebar-collapsed: 55px;
  --sidebar: var(--sidebar-expanded);
  --shell-padding: 10px;
  --shell-gap: 12px;
  --layout-padding: 10px;
  --layout-gap: 12px;
  --layout-column-gap: var(--layout-gap);
  --layout-row-gap: var(--layout-gap);
  --panel-padding: var(--scale-panel-padding);
  --tab-height: var(--scale-toolbar-height);
  --tab-padding-y: 7px;
  --tab-padding-x: 10px;
  --control-height: var(--scale-control-height);
  --control-padding-y: 7px;
  --control-padding-x: 9px;
  --button-height: var(--scale-button-height);
  --button-padding-y: 7px;
  --button-padding-x: 10px;
  --form-gap: var(--scale-gap);
  --section-gap: var(--scale-gap);
  --nav-item-height: 46px;
  --nav-item-padding: 10px;
  --nav-icon-size: 30px;
  --motion-premium-in: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-premium-out: cubic-bezier(0.7, 0, 0.84, 0);
  --motion-premium-press: cubic-bezier(0.34, 1.56, 0.64, 1);
  --motion-premium-fast: 120ms;
  --motion-premium-base: 220ms;
  --motion-premium-slow: 340ms;
  --muted-2: #98a2b3;
  --border-soft: #e7ebf1;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #f1f5f9;
  --topbar-bg: #ffffff;
  --mobile-topbar-bg: rgba(255, 255, 255, 0.96);
  --mobile-topbar-border: var(--border);
  --mobile-topbar-shadow: 0 10px 22px rgba(15, 23, 42, 0.07);
  --advanced-bg: #f8fbfd;
  --advanced-open-bg: #ffffff;
  --advanced-border: #dce6ef;
  --advanced-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
  --advanced-summary-bg: #ffffff;
  --advanced-summary-open-bg: #f9fafc;
  --advanced-summary-color: #344054;
  --advanced-summary-hover-bg: #f3f8fd;
  --advanced-summary-hover-color: #255a9c;
  --advanced-summary-shadow: 0 1px 2px rgba(16, 24, 40, 0.03);
  --advanced-arrow: #64748b;
  --mobile-chat-surface: #ffffff;
  --mobile-chat-surface-2: #fbfcfe;
  --mobile-chat-border: #dce6ef;
  --mobile-chat-sidebar-bg: #f8fbfa;
  --mobile-chat-sidebar-shadow: 0 22px 50px rgba(15, 23, 42, 0.22);
  /* ===== 浮层层级总表（z-index 单一出处，从低到高）=====
     约定：同一层用同一 token；同族内的细分用 calc(token + N) 保留次序，
     不要再到处写裸数字。组件内部的局部堆叠(1~6、贴顶 sticky 80/86/120 等)不在此表。 */
  --z-sidebar-drawer: 1300;   /* 手机端侧栏抽屉（聊天侧栏等） */
  --z-float-toolbar: 3000;    /* 手机端浮动工具条 / 返回按钮 */
  --z-tool-mask: 6000;        /* 工具箱弹窗族（案例库/工具详情/运行/选图，+200/+300/+400） */
  --z-account: 9000;          /* 账户·登录全屏弹窗 */
  --z-overlay: 10000;         /* 悬浮输入/菜单/tooltip/裁剪/验证码等功能浮层 */
  --z-modal: 12000;           /* 基础弹窗遮罩 .modal-mask */
  --z-modal-pick: 12100;      /* 选图模式下被提到最前的媒体库 */
  --z-modal-priority: 13000;  /* 预览/详情类弹窗（图片预览、结果/媒体详情） */
  --z-modal-confirm: 15000;   /* 确认弹窗（弹窗里最高） */
  --z-select-mask: 16000;     /* 手机端自绘选择表:像原生 select 一样恒在最顶(高于所有弹窗 --z-modal-confirm 15000,低于拖拽幽灵)。从弹窗内唤起的 select 才点得到 */
  --z-drag-ghost: 99999;      /* 拖拽跟随幽灵（在所有弹窗之上、提示之下） */
  --z-toast: 999999;          /* 系统提示 toast（永远最顶） */
  --accent-soft: #eaf2fb;
  --blue-soft: #eef5ff;
  --danger-soft: #fff3f1;
  --danger-border: #f1c5be;
  --ok-soft: #e9f6f1;
  --ok-border: #bfe3d6;
  --warning-soft: #fdf4e7;
  --warning-border: #f0d9b0;
  --info: #2563a7;
  --info-soft: #eef5ff;
  --border-strong: #d3dce9;
  /* v2 配色升级：蓝锚点 + 靛紫副色 + 蓝→靛→紫品牌渐变 + 暖琥珀高光，告别单一蓝的死板 */
  --accent-2: #6d5ef0;
  --accent-2-strong: #574bd4;
  --accent-2-soft: #ecebfd;
  --highlight: #f2922f;
  --highlight-strong: #d97a18;
  --highlight-soft: #fdf1e2;
  --brand-gradient: linear-gradient(135deg, #2f6db7 0%, #4f63dd 52%, #7a59e0 100%);
  --brand-gradient-strong: linear-gradient(135deg, #285f9f 0%, #4554c8 52%, #6a46cf 100%);
  --brand-gradient-soft: linear-gradient(135deg, #eaf2fb 0%, #edeffe 58%, #f3ecfd 100%);
  --brand-glow: 0 10px 26px rgba(79, 99, 221, 0.24);
  --brand-glow-strong: 0 16px 34px rgba(79, 99, 221, 0.3);
  /* 面板字号 / 高度档位（灵感广场分享面板与项目库共用的唯一真源）。
     这两处界面此前各自散着 15.5 / 13.5 / 13 / 12.5 / 12 / 11.5 六七档字号，
     同一层级的标题在两个面板里差半个像素，看着就是没对过版。现在只有四档字号、三档高度，
     两边一律引用这里；面板要整体压一档（比如手机）就在自己的作用域里改这几个变量，别写裸数值。
       title 面板标题 / body 控件与正文 / label 字段标签·分区标题 / note 副说明·状态 */
  --panel-fs-title: 15.5px;
  --panel-fs-body: 13.5px;
  --panel-fs-label: 12px;
  --panel-fs-note: 11.5px;
  --panel-h-control: 38px;
  --panel-h-action: 34px;
  --panel-h-pill: 25px;
  --studio-canvas-surface-light: #f4f7fa;
  /* 亮色网格 .24→.42:与画布工作台直绘令牌(--canvas-grid-line-light)同值同源——太淡时白底图片边界看不清(用户报修) */
  --studio-canvas-grid-light: rgba(184, 197, 214, 0.42);
  --studio-canvas-grid-image-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M0 .5H28M.5 0V28' fill='none' stroke='%23b8c5d6' stroke-opacity='.42' stroke-width='1'/%3E%3C/svg%3E");
  --studio-canvas-surface-dark: #121316;
  /* 暗色网格亮度:0.045 看不清 → 0.10 又太抢 → 0.08 定稿(2026-07 用户两轮反馈) */
  --studio-canvas-grid-dark: rgba(255, 255, 255, 0.08);
  --studio-canvas-grid-image-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M0 .5H28M.5 0V28' fill='none' stroke='%23ffffff' stroke-opacity='.08' stroke-width='1'/%3E%3C/svg%3E");
  --canvas-selection-frame-color: rgba(47, 109, 183, 0.92);
  --canvas-selection-frame-fill: rgba(47, 109, 183, 0.035);
  --canvas-selection-frame-inset: rgba(255, 255, 255, 0.62);
  --canvas-selection-subtract-frame-color: rgba(217, 45, 32, 0.92);
  --canvas-selection-subtract-frame-fill: rgba(217, 45, 32, 0.055);
  --canvas-selection-frame-radius: 14px;
  --canvas-selection-frame-line-width: 1.5px;
  --canvas-selection-frame-dash-on: 7;
  --canvas-selection-frame-dash-off: 5;
  --radius-xs: 6px;
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 14px;
  /* v2 分层阴影:注入靛蓝冷调(38,52,92)代替死板纯灰,卡片通透且与品牌呼应 */
  --shadow-soft: 0 1px 2px rgba(38, 52, 92, 0.05), 0 8px 18px -6px rgba(38, 52, 92, 0.12);
  --shadow-popover: 0 4px 10px rgba(38, 52, 92, 0.08), 0 28px 56px -14px rgba(38, 52, 92, 0.24);
  --shadow-card: 0 1px 2px rgba(38, 52, 92, 0.05), 0 6px 14px -5px rgba(38, 52, 92, 0.1);
  --focus-ring: 0 0 0 3px rgba(47, 109, 183, 0.16);
  /* 〔2026-06-23 改为 FLIP 丝滑动画〕侧栏折叠/展开:内容(.layout,~7000节点)用 JS FLIP(GPU transform)平滑滑动
     ——margin 仍瞬时落位(不逐帧重排),只用 translateX 在合成层里滑(实测最重模块 batch/canvas 仍 ~60fps、
     起始栅格化尖峰仅 8~10ms,见 setSidebarCollapsed)。轨道(.topbar)是 position:fixed 的轻量栏(~100节点),
     其宽度 + 按钮便宜地用真过渡同步滑动,时长即此变量。
     〔历史〕本变量曾为 0ms(瞬切无动画):当时用 margin/width 过渡会逐帧重排 7000 节点锁 30fps,且旧注释称
     FLIP 有 ~116ms 尖峰——实测在合成层上并非如此(尖峰是 0.75×ratio 这类瞬时,可忽略)。改值前务必重测帧率。
     〔2026-06-23 退回 0ms〕设成 260ms 会让 ~100 个轨道按钮每帧动画 box-shadow/背景渐变/border-color(昂贵 paint)
     → 折叠卡;且 border-color 不再随几何瞬切 → 黑框闪复现(黑框修复依赖它瞬切)。故按钮保持瞬切,丝滑由
     #appLayout 的 FLIP(内容滑) + .topbar 宽度过渡(轨道边滑) 负责,不靠按钮逐帧动画。 */
  --sidebar-motion: 0ms;
  --sidebar-nav-row-height: 53px;
  --sidebar-icon-size: 32px;
  --app-zoom: 1;
  /* 视觉升级：字号/间距/控件高度上调，告别"过小过挤"的廉价感（专业站 body≈13px、控件≈33px）。 */
  --scale-font-body: 12.5px;
  --scale-font-label: 11.5px;
  --scale-font-caption: 10.5px;
  --scale-font-title: 16px;
  --scale-font-section: 15px;
  --scale-control-height: 33px;
  --scale-button-height: 33px;
  --scale-toolbar-height: 34px;
  --scale-row-height: 38px;
  --scale-panel-padding: 13px;
  --scale-card-padding: 11px;
  --scale-gap: 9px;
  --scale-radius-panel: 12px;
  --scale-radius-control: 9px;
  /* 生成进度条唯一视觉契约：数值和文案由 gen-monitor.js 统一，所有页面只消费这里的视觉令牌。 */
  --generation-progress-height: 3px;
  --generation-progress-radius: 3px;
  --generation-progress-track: rgba(100, 116, 139, 0.2);
  --generation-progress-fill: linear-gradient(90deg, #0ea5e9, #6366f1);
  --generation-progress-transition: width 0.9s cubic-bezier(0.22, 0.8, 0.28, 1);
  --generation-progress-indeterminate-size: 42%;
  --generation-progress-indeterminate-duration: 1.25s;
}

/*
 * 全站生成进度条组件。
 * 容器可保留自身的定位/外边距，但轨道、填充与不确定态不得在业务模块里另起一套视觉。
 */
:where(.site-generation-progress) {
  position: relative;
  height: var(--generation-progress-height);
  overflow: hidden;
  border-radius: var(--generation-progress-radius);
  background: var(--generation-progress-track);
}

:where(.site-generation-progress-fill) {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--generation-progress-fill);
  transition: var(--generation-progress-transition);
}

@keyframes site-generation-progress-indeterminate {
  from { left: calc(-1 * var(--generation-progress-indeterminate-size)); }
  to { left: 100%; }
}

:where(
  .site-generation-progress-fill.indet,
  .site-generation-progress-fill.is-indeterminate,
  .site-generation-progress.is-indeterminate > .site-generation-progress-fill
) {
  position: absolute;
  top: 0;
  width: var(--generation-progress-indeterminate-size) !important;
  animation: site-generation-progress-indeterminate var(--generation-progress-indeterminate-duration) ease-in-out infinite;
}

/* 文案是可选附属信息：没有 ETA 时不为阶段词或空节点预留高度。 */
:where(.site-generation-progress-label[hidden], .site-generation-progress-label:empty) {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  :where(.site-generation-progress-fill) {
    transition: none;
  }
  :where(
    .site-generation-progress-fill.indet,
    .site-generation-progress-fill.is-indeterminate,
    .site-generation-progress.is-indeterminate > .site-generation-progress-fill
  ) {
    left: 0;
    opacity: 0.7;
    animation: none;
  }
}

/* 文本选区统一品牌蓝(默认深蓝选区与基调不符) */
::selection {
  background: rgba(47, 109, 183, 0.18);
  color: inherit;
}

/* 视觉方案v1:全站细滚动条(默认粗灰滚动条是"系统感"的最大来源之一) */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(100, 116, 139, 0.42) transparent;
}
*::-webkit-scrollbar {
  width: 9px;
  height: 9px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: rgba(100, 116, 139, 0.36);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: rgba(83, 90, 104, 0.58);
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-corner {
  background: transparent;
}
body.theme-dark * {
  scrollbar-color: rgba(148, 163, 184, 0.34) transparent;
}
body.theme-dark *::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.3);
  border: 2px solid transparent;
  background-clip: padding-box;
}
body.theme-dark *::-webkit-scrollbar-thumb:hover {
  background: rgba(148, 163, 184, 0.5);
  border: 2px solid transparent;
  background-clip: padding-box;
}

/* 性能根因:backdrop-filter(毛玻璃模糊)在普通显卡上每一帧都要重算"背后内容",是界面卡顿的常见根因
   ——高端机无感、普通机明显卡。而本项目这些元素背景多为 ≥96% 不透明,模糊几乎看不出。
   因此除必要的浮层遮罩(.modal-mask / .context-menu)外一律关闭,显著降低重绘成本、滚动与切换更跟手。
   极少数确实需要玻璃质感的独立元素用 data-ui-glass 显式申请，避免继续扩充类名黑名单。 */
body:not(.auth-required) *:not(.modal-mask):not(.context-menu):not([data-ui-glass]) {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* 性能:超长列表用 content-visibility 跳过"屏幕外"项的布局与绘制,滚动明显更顺。
   contain-intrinsic-size 用 auto 关键字记忆已渲染过的真实尺寸,避免滚动条跳动;阴影多在 hover 态、静态为边框,裁剪风险低。 */
body:not(.auth-required) :is(.job-row, .task-list-row, .task-row, .case-row) {
  content-visibility: auto;
  contain-intrinsic-size: auto 44px;
}
/* 注意:媒体库卡片(.workflow-media-library-card)不能用 content-visibility——
   其"记忆尺寸"会与挑选模式的 flex 定高网格交互,把整列行高压成 ~55px 细条(2026-06-11 实测)。
   媒体库本身已有分页+图片懒加载,无需此优化。收藏案例卡保留。 */
body:not(.auth-required) .favorite-case-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 188px;
}
body:not(.auth-required) .text-chat-message {
  content-visibility: auto;
  contain-intrinsic-size: auto 72px;
}
/* 历史项占位高度贴近实际项高,避免重建时先撑 72px 再缩回造成整列跳动 */
body:not(.auth-required) .text-chat-history-item {
  content-visibility: auto;
  contain-intrinsic-size: auto 76px;
}
body:not(.auth-required) .hl-grid > .hl-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 280px;
}

/* Premium motion pass: restrained micro-interactions across the app. */

@keyframes hui-fade-up {
  from {
    opacity: 0;
    transform: translate3d(0, 8px, 0) scale(0.992);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@media (hover: hover) and (pointer: fine) {
  body:not(.auth-required) .module-tab .ui-icon {
    transition: color var(--motion-premium-base) var(--motion-premium-in), background-color var(--motion-premium-base) var(--motion-premium-in), border-color var(--motion-premium-base) var(--motion-premium-in);
  }
}

@keyframes hui-scale-in {
  from {
    opacity: 0;
    transform: translate3d(0, 10px, 0) scale(0.975);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes hui-sheet-in {
  from {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes hui-backdrop-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes hui-toast-in {
  from {
    opacity: 0;
    transform: translate3d(0, 10px, 0) scale(0.98);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes hui-menu-in {
  from {
    opacity: 0;
    transform: translate3d(0, 6px, 0) scale(0.985);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes hui-progress-flow {
  from {
    background-position: 0 0;
  }

  to {
    background-position: 88px 0;
  }
}

@keyframes hui-theme-toggle-icon {
  0% {
    opacity: 1;
    filter: brightness(1) saturate(1) drop-shadow(0 0 0 rgba(47, 109, 183, 0));
    transform: translate3d(0, 0, 0) scale(1);
  }

  30% {
    opacity: 0.7;
    filter: brightness(1.22) saturate(1.18) drop-shadow(0 0 8px rgba(47, 109, 183, 0.22));
    transform: translate3d(0, 1px, 0) scale(0.78);
  }

  64% {
    opacity: 1;
    filter: brightness(1.12) saturate(1.12) drop-shadow(0 0 12px rgba(47, 109, 183, 0.24));
    transform: translate3d(0, -1px, 0) scale(1.1);
  }

  82% {
    opacity: 1;
    filter: brightness(1.05) saturate(1.06) drop-shadow(0 0 6px rgba(47, 109, 183, 0.14));
    transform: translate3d(0, 0, 0) scale(0.98);
  }

  100% {
    opacity: 1;
    filter: brightness(1) saturate(1) drop-shadow(0 0 0 rgba(47, 109, 183, 0));
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes hui-theme-toggle-surface {
  0% {
    filter: brightness(1) saturate(1);
    transform: translate3d(0, 0, 0) scale(1);
  }

  34% {
    filter: brightness(1.04) saturate(1.1);
    transform: translate3d(0, 0, 0) scale(0.985);
  }

  64% {
    filter: brightness(1.06) saturate(1.14);
    transform: translate3d(0, 0, 0) scale(1.018);
  }

  84% {
    filter: brightness(1.02) saturate(1.06);
    transform: translate3d(0, 0, 0) scale(0.997);
  }

  100% {
    filter: brightness(1) saturate(1);
    transform: translate3d(0, 0, 0) scale(1);
  }
}

body.theme-switching {
  user-select: none;
}

/* 主题切换的交互锁定是引擎级的:View Transition 期间真实 DOM 的渲染被搬进快照树,整页不可命中,
   给 ::view-transition 设 pointer-events:none 也救不回(实测事件只会落到 html)。
   「切完还要等两秒」的解法收口在 JS 侧的 THEME_TRANSITION_DURATION:旧值 1062ms 的缓动前 30% 就完成了
   ~80% 扩散,其余时间都在磨边+锁交互;时长收短后视觉扩散完成的瞬间交互即解锁。别再试图用 CSS 放行。 */
::view-transition-group(root) {
  animation: none;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  backface-visibility: hidden;
  mix-blend-mode: normal;
}

body:not(.auth-required) #themeToggleBtn.is-theme-switching {
  animation: hui-theme-toggle-surface 774ms cubic-bezier(0.22, 1, 0.36, 1) both;
  will-change: filter, transform;
}

body:not(.auth-required) #themeToggleBtn:is(:hover, :active) {
  transform: none;
}

body:not(.auth-required) #themeToggleBtn.is-theme-switching .ui-icon {
  animation: hui-theme-toggle-icon 774ms cubic-bezier(0.22, 1, 0.36, 1) both;
  transform-origin: center;
  will-change: opacity, filter, transform;
  transition:
    color 180ms cubic-bezier(0.16, 1, 0.3, 1),
    background-color 180ms cubic-bezier(0.16, 1, 0.3, 1);
}

body:not(.auth-required) :is(
  button:not([data-ui-compact-control]),
  .primary,
  .secondary,
  .danger,
  .icon-button,
  .module-tab,
  .tool-mode-tab,
  .tab,
  .button-link,
  .account-action,
  .modal-close,
  .canvas-dock-button,
  .thumb-preview
) {
  transition:
    box-shadow var(--motion-premium-fast) var(--motion-premium-in),
    border-color var(--motion-premium-fast) var(--motion-premium-in),
    background-color var(--motion-premium-fast) var(--motion-premium-in),
    color var(--motion-premium-fast) var(--motion-premium-in),
    opacity var(--motion-premium-fast) var(--motion-premium-in);
}

body:not(.auth-required) :is(
  input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  textarea,
  select,
  .advanced,
  .text-chat-shell,
  .text-chat-composer,
  .canvas-ai-composer,
  .workflow-toolbar,
  .infinite-canvas-toolbar,
  .workflow-project-card,
  .canvas-project-card,
  .favorite-case-card,
  .case-row,
  .task-list-row,
  .task-row,
  .job-select,
  .case-select,
  .settings-provider-card,
  .gateway-card,
  .model-route-card
) {
  transition:
    border-color var(--motion-premium-base) var(--motion-premium-in),
    box-shadow var(--motion-premium-fast) var(--motion-premium-in),
    background-color var(--motion-premium-base) var(--motion-premium-in),
    opacity var(--motion-premium-base) var(--motion-premium-in);
}

body:not(.auth-required) :is(
  input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  textarea,
  select,
  button:not([data-ui-compact-control]):not(.ob-rail-step),
  [role="button"],
  .module-tab,
  .tool-mode-tab,
  .account-action,
  .thumb-preview
):focus-visible {
  outline: 0;
  border-color: color-mix(in srgb, var(--accent) 72%, #ffffff);
  box-shadow:
    0 0 0 3px rgba(47, 109, 183, 0.16),
    0 8px 22px rgba(15, 23, 42, 0.08);
  /* 焦点环必须即时出现：否则会因 box-shadow 220ms 过渡而"蓝色阴影延迟一下才显示"。 */
  transition: box-shadow 0.1s ease-out, border-color 0.1s ease-out;
}

body:not(.auth-required) :is(button, .primary, .secondary, .danger, .icon-button, .module-tab, .tool-mode-tab):not([data-ui-compact-control])[disabled],
body:not(.auth-required) :is(button, .primary, .secondary, .danger, .icon-button, .module-tab, .tool-mode-tab):not([data-ui-compact-control])[aria-disabled="true"] {
  transform: none;
  filter: saturate(0.92);
}

@media (hover: hover) and (pointer: fine) {
  body:not(.auth-required) :is(
    .advanced,
    .workflow-project-card,
    .canvas-project-card,
    .favorite-case-card,
    .case-row,
    .task-list-row,
    .task-row,
    .job-select,
    .case-select,
    .settings-provider-card,
    .gateway-card,
    .model-route-card
  ):hover {
    border-color: color-mix(in srgb, var(--accent) 34%, var(--border));
    box-shadow: 0 16px 32px rgba(15, 23, 42, 0.1);
  }
}

body:not(.auth-required) .module-tab.active .ui-icon,
body:not(.auth-required) .tool-mode-tab.active .ui-icon {
  transform: none;
  transition: color var(--motion-premium-base) var(--motion-premium-in), background-color var(--motion-premium-base) var(--motion-premium-in), border-color var(--motion-premium-base) var(--motion-premium-in);
}

/* 面板入场的唯一选择器位于 styles.part4.css 的 late layer。
   这里仅保留关键帧定义，避免同一语义在两层各维护一份并产生特异性竞态。 */

body:not(.auth-required) :is(
  .favorite-case-card,
  .case-row,
  .task-list-row,
  .task-row,
  .job-select,
  .case-select,
  .workflow-project-card,
  .canvas-project-card,
  .settings-provider-card,
  .gateway-card,
  .model-route-card,
  .thumb,
  .text-chat-history-item,
  .text-chat-message
) {
  animation: hui-fade-up var(--motion-premium-base) var(--motion-premium-in) both;
}

body:not(.auth-required) .modal-mask:not([hidden]) {
  animation: hui-backdrop-in 160ms ease-out both;
}

body:not(.auth-required) .modal-mask:not([hidden]) .modal-panel {
  animation: hui-scale-in var(--motion-premium-base) var(--motion-premium-in) both;
  transform-origin: center center;
}

body:not(.auth-required) :is(.account-usage-modal, .canvas-image-crop-mask, .canvas-image-edit-mask, .canvas-video-edit-mask, .panorama-preview-mask):not([hidden]) .modal-panel {
  animation-name: hui-sheet-in;
}

body:not(.auth-required) .context-menu:not([hidden]),
body:not(.auth-required) > .graphdialog:not([hidden]),
body:not(.auth-required) > .litegraph.graphdialog:not([hidden]) {
  animation: hui-menu-in var(--motion-premium-base) var(--motion-premium-in) both;
  transform-origin: top left;
}

body:not(.auth-required) .toast:not([hidden]) {
  animation: hui-toast-in var(--motion-premium-base) var(--motion-premium-in) both;
}

body:not(.auth-required) :is(.progress-bar > span, .job-progress-fill, .task-progress-fill, .usage-bar > span) {
  background-size: 88px 100%;
  animation: hui-progress-flow 1.45s linear infinite;
}

body:not(.auth-required) :is(details.advanced, .settings-advanced-direct) > summary {
  transition:
    border-color var(--motion-premium-base) var(--motion-premium-in),
    background-color var(--motion-premium-base) var(--motion-premium-in),
    box-shadow var(--motion-premium-fast) var(--motion-premium-in);
}

body:not(.auth-required) :is(details.advanced, .settings-advanced-direct)[open] > summary {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  box-shadow: inset 0 -1px 0 rgba(47, 109, 183, 0.12);
}

body:not(.auth-required) .text-chat-shell.text-history-open .text-chat-sidebar,
body:not(.auth-required) .text-chat-history-backdrop:not([hidden]) {
  animation: hui-sheet-in var(--motion-premium-base) var(--motion-premium-in) both;
}

body:not(.auth-required) :is(.workflow-node, .infinite-card, .workflow-media-overlay-thumb, .workflow-lite-canvas, .workflow-stage-wrap, .infinite-canvas-stage, .infinite-canvas-content) {
  animation: none;
}

@media (max-width: 820px) {
  body:not(.auth-required) .modal-mask:not([hidden]) .modal-panel {
    animation-name: hui-sheet-in;
    animation-duration: 200ms;
  }

  body:not(.auth-required) :is(.favorite-case-card, .case-row, .task-list-row, .task-row, .workflow-project-card, .thumb, .text-chat-history-item, .text-chat-message) {
    animation-duration: 180ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  body:not(.auth-required) *,
  body:not(.auth-required) *::before,
  body:not(.auth-required) *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}

/* Mobile settings consistency: match the compact tool-page typography. */
@media (max-width: 820px) {
  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .settings-section-title,
  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .gateway-card-head,
  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .gateway-category-head {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) !important;
    align-items: start !important;
    gap: 4px !important;
    padding: 0 2px !important;
    text-align: left !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] :is(
    .settings-section-title strong,
    .gateway-card-head strong,
    .gateway-category-head strong,
    .gateway-category-card strong,
    .model-route-head strong
  ) {
    font-size: 13px !important;
    line-height: 1.18 !important;
    font-weight: 820 !important;
    letter-spacing: 0 !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] :is(
    .settings-section-title span,
    .gateway-card-head span,
    .gateway-category-head span,
    .gateway-category-card span,
    .model-route-head span,
    .settings-provider-help
  ) {
    margin-top: 0 !important;
    color: var(--muted) !important;
    font-size: 10px !important;
    line-height: 1.28 !important;
    text-align: left !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .settings-advanced-direct {
    width: 100% !important;
    max-width: 100% !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .settings-advanced-direct > summary {
    min-height: 29px !important;
    padding: 0 10px !important;
    border-radius: 11px !important;
    font-size: 10.5px !important;
    line-height: 1 !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] :is(.gateway-card, .settings-provider-card, .gateway-key-manager, .gateway-category-card) {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box !important;
    padding: 10px !important;
    border-radius: 14px !important;
    gap: 8px !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] :is(.gateway-actions, .model-route-toolbar, .model-route-actions) {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 6px !important;
    width: 100% !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] .gateway-actions select {
    grid-column: 1 / -1 !important;
  }

  body:not(.auth-required) #appLayout.settings-layout[data-module-panel="settingsModule"] :is(.gateway-actions button, .model-route-toolbar button, .model-route-actions button) {
    min-width: 0 !important;
    width: 100% !important;
    min-height: 29px !important;
    height: 29px !important;
    padding: 0 7px !important;
    border-radius: 10px !important;
    font-size: 10.5px !important;
  }
}

* {
  box-sizing: border-box;
}

html {
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family:
    Inter, "Segoe UI", "Microsoft YaHei", Arial, sans-serif;
  font-size: var(--font-ui);
  min-height: 100vh;
}

body.sidebar-collapsed {
  --sidebar: var(--sidebar-collapsed);
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  white-space: nowrap;
}

.topbar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 10;
  width: var(--sidebar);
  height: 100vh;
  padding: 18px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 18px;
  background: var(--topbar-bg);
  border-right: 1px solid var(--border);
  box-shadow: 10px 0 28px rgba(26, 32, 44, 0.05);
  overflow-x: hidden;
  overflow-y: auto;
  /* 轨宽随 --sidebar「瞬时落位」,不做几何过渡——真正生效的是 styles.part2.css 的
     .topbar{transition:none}。这里不要再加 width/padding 过渡:animating 它们会让浏览器每帧
     重排 ~7000 节点的内容树、锁 30fps(详见上方 --sidebar-motion 注释)。原 `transition: width
     .18s, padding .18s` 已被 part2 盖掉、属死代码,删除以免误导/加载顺序变动时复活卡顿。 */
}

h1,
h2,
p {
  margin: 0;
}

h1 {
  font-size: var(--font-title);
  font-weight: 760;
}

h2 {
  font-size: var(--font-section-title);
  font-weight: 800;
  letter-spacing: -0.012em;
}

.topbar p,
.monitor-header p {
  color: var(--muted);
  margin-top: 4px;
}

.brand-block {
  min-width: 0;
  padding-bottom: 16px;
  border-bottom: 1px solid #edf0f5;
}

.brand-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: start;
}

.brand-text {
  min-width: 0;
}

.brand-short {
  display: none;
}

.sidebar-toggle {
  min-width: 52px;
  min-height: 34px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #f9fafc;
  color: #344054;
  cursor: pointer;
}

.module-nav {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  align-items: stretch;
}

.module-tab {
  position: relative;
  display: grid;
  grid-template-rows: 20px 18px;
  gap: 4px;
  align-content: center;
  justify-items: start;
  min-height: 68px;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  color: var(--text);
  padding: 13px 14px;
  cursor: pointer;
}

.module-tab[draggable="true"] {
  cursor: grab;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.module-tab.dragging {
  opacity: 0.72;
  cursor: grabbing;
}

.module-tab.drag-ready {
  border-color: rgba(47, 109, 183, 0.65);
  background: #eef6ff;
  box-shadow: inset 3px 0 0 var(--accent), 0 0 0 3px rgba(47, 109, 183, 0.12);
}

.workflow-template-drag-ghost {
  position: fixed;
  left: 0;
  top: 0;
  z-index: var(--z-drag-ghost);
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 9px;
  align-items: center;
  min-width: 190px;
  max-width: min(280px, calc(100vw - 24px));
  padding: 9px 11px;
  border: 1px solid rgba(47, 109, 183, 0.34);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.94);
  color: var(--accent-strong);
  box-shadow: 0 16px 38px rgba(15, 23, 42, 0.18);
  /* 拖拽幽灵随指针逐帧移动,0.94 近不透明底上的 backdrop blur = 每帧白算一次模糊——删 */
  pointer-events: none;
  will-change: transform;
}

.workflow-template-drag-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: #e8f1fb;
  color: var(--accent-strong);
}

.workflow-template-drag-icon svg {
  width: 18px;
  height: 18px;
  stroke-width: 1.8;
}

.workflow-template-drag-copy {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.workflow-template-drag-copy b {
  overflow: hidden;
  color: #12385a;
  font-size: 13px;
  font-weight: 830;
  line-height: 1.18;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.workflow-template-drag-copy small {
  overflow: hidden;
  color: #5c7893;
  font-size: 11px;
  font-weight: 650;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.module-template-dragging {
  cursor: grabbing;
}

/* 「添加模块」菜单拖出来的标签：干净的药丸 chip(强调色圆点 + 名称)，跟随光标/手指。 */
.module-place-ghost {
  position: fixed;
  left: 0;
  top: 0;
  z-index: var(--z-drag-ghost);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: min(220px, calc(100vw - 24px));
  padding: 7px 14px 7px 11px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--menu-accent, var(--accent)) 42%, transparent);
  background: rgba(255, 255, 255, 0.97);
  color: #12385a;
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.22);
  backdrop-filter: blur(10px);
  pointer-events: none;
  will-change: transform;
}
.module-place-ghost-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--menu-accent, var(--accent));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--menu-accent, var(--accent)) 18%, transparent);
}
.module-place-ghost-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.theme-dark .module-place-ghost {
  background: rgba(20, 30, 48, 0.96);
  color: #e8f1fc;
  border-color: color-mix(in srgb, var(--menu-accent, var(--accent)) 50%, transparent);
}

.app-tooltip {
  position: fixed;
  /* 提示层必须压过**所有**弹窗/浮层,否则在弹窗里悬停按钮时提示被盖在下面 = 看起来「完全没有提示」。
     原来是 calc(var(--z-overlay) + 30)=10030,而 #workflowProjectModal 之类的弹窗是 12001,
     于是项目库里那排图标按钮怎么悬停都不出提示(用户报「都不知道是干什么的」)。
     这是全站唯一的提示层,提到最顶层收口一次,别再给单个弹窗打补丁。 */
  z-index: 100001;
  width: max-content;
  max-width: min(260px, calc(100vw - 20px));
  padding: 6px 8px;
  border: 1px solid rgba(184, 202, 222, 0.68);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.95);
  color: #21384f;
  box-shadow: 0 8px 18px rgba(15, 23, 42, 0.12);
  backdrop-filter: blur(10px);
  opacity: 0;
  transform: translateY(2px) scale(0.98);
  transition: opacity 0.12s ease, transform 0.12s ease;
  pointer-events: none;
}

.app-tooltip.visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.app-tooltip-title {
  margin-bottom: 2px;
  color: #112d49;
  font-size: 11.25px;
  font-weight: 720;
  line-height: 1.22;
  white-space: nowrap;
}

.app-tooltip.title-only .app-tooltip-title {
  margin-bottom: 0;
}

.app-tooltip-detail {
  color: #536b83;
  font-size: 10.75px;
  font-weight: 540;
  line-height: 1.34;
  white-space: normal;
}

body.theme-dark:not(.auth-required) .workflow-template-drag-ghost,
body.theme-dark .workflow-template-drag-ghost {
  border-color: rgba(90, 166, 232, 0.38);
  background: rgba(18, 21, 28, 0.94);
  box-shadow: 0 18px 42px rgba(0, 0, 0, 0.42);
}

body.theme-dark:not(.auth-required) .workflow-template-drag-icon,
body.theme-dark .workflow-template-drag-icon {
  background: rgba(47, 109, 183, 0.22);
  color: #9cc4ec;
}

body.theme-dark:not(.auth-required) .workflow-template-drag-copy b,
body.theme-dark .workflow-template-drag-copy b {
  color: #e7eef9;
}

body.theme-dark:not(.auth-required) .workflow-template-drag-copy small,
body.theme-dark .workflow-template-drag-copy small {
  color: #9db0c8;
}

body.theme-dark:not(.auth-required) .app-tooltip,
body.theme-dark .app-tooltip {
  border-color: rgba(83, 90, 104, 0.78);
  background: rgba(18, 21, 28, 0.96);
  color: #dbe7f5;
  box-shadow: 0 18px 42px rgba(0, 0, 0, 0.42);
}

body.theme-dark:not(.auth-required) .app-tooltip-title,
body.theme-dark .app-tooltip-title {
  color: #e7eef9;
}

body.theme-dark:not(.auth-required) .app-tooltip-detail,
body.theme-dark .app-tooltip-detail {
  color: #aebfd6;
}

.module-tab strong {
  display: block;
  width: 100%;
  font-size: 15px;
  line-height: 20px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.module-tab span {
  display: block;
  width: 100%;
  color: var(--muted);
  font-size: 12px;
  line-height: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.module-tab.active {
  border-color: rgba(47, 109, 183, 0.55);
  background: #eef7f3;
  box-shadow: inset 4px 0 0 var(--accent);
}

.module-tab.drag-target {
  border-color: var(--accent);
  background: #eaf2fb;
  box-shadow: inset 4px 0 0 var(--accent), 0 0 0 3px rgba(47, 109, 183, 0.14);
}

.topbar .top-actions {
  margin-top: auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  align-items: stretch;
}

.topbar .state-pill,
.topbar .icon-button {
  justify-content: center;
  min-height: 40px;
}

.topbar .sidebar-refresh,
.topbar .sidebar-theme {
  width: 100%;
  min-width: 0;
  border-color: #bfd0ea;
  background: #f7faff;
  color: var(--blue);
}

.top-actions,
.monitor-actions,
.command-row,
.toggle-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.layout {
  display: grid;
  grid-template-columns: minmax(420px, 0.78fr) minmax(0, 1.22fr);
  column-gap: var(--layout-column-gap);
  row-gap: var(--layout-row-gap);
  margin-left: var(--sidebar);
  padding: var(--layout-padding);
  min-height: 100vh;
  align-items: stretch;
  /* 内容左缩进随 --sidebar 瞬时落位,不做 margin-left 过渡——生效的是 styles.part2.css 的
     .layout{transition:none}。animating margin-left 会每帧重排整棵内容树锁 30fps(见 --sidebar-motion
     注释)。原 `transition: margin-left .18s` 已被 part2 盖掉、属死代码,删除以免误导/复活卡顿。 */
}

body.sidebar-collapsed .topbar {
  padding: 14px 10px;
}

body.sidebar-collapsed .brand-block {
  padding-bottom: 12px;
}

body.sidebar-collapsed .brand-row {
  grid-template-columns: 1fr;
  justify-items: center;
  gap: 8px;
}

body.sidebar-collapsed .brand-full,
body.sidebar-collapsed .brand-text p,
body.sidebar-collapsed .module-tab strong,
body.sidebar-collapsed .module-tab span {
  display: none;
}

body.sidebar-collapsed .brand-short {
  display: inline;
}

body.sidebar-collapsed .brand-text {
  text-align: center;
}

body.sidebar-collapsed .sidebar-toggle {
  width: 100%;
  min-width: 0;
  padding: 6px 4px;
  font-size: 12px;
}

body.sidebar-collapsed .module-nav {
  gap: 8px;
}

body.sidebar-collapsed .module-tab {
  min-height: 48px;
  grid-template-rows: 1fr;
  justify-items: center;
  align-items: center;
  align-content: center;
  padding: 10px 6px;
  text-align: center;
}

body.sidebar-collapsed .module-tab::before {
  content: "";
  font-weight: 760;
  font-size: 13px;
}

body.sidebar-collapsed .module-tab.active {
  box-shadow: inset 0 -3px 0 var(--accent);
}

body.sidebar-collapsed .topbar .state-pill,
body.sidebar-collapsed .topbar .icon-button {
  min-height: 36px;
  padding: 8px 4px;
  font-size: 0;
}

body.sidebar-collapsed .topbar .state-pill::before,
body.sidebar-collapsed .topbar .icon-button::before {
  content: attr(data-short);
  font-size: 12px;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  min-width: 0;
}

.layout > .panel {
  min-height: calc(100vh - 32px);
  width: 100%;
}

.workbench {
  overflow: hidden;
}

.monitor {
  padding: 18px;
  overflow: hidden;
}

.layout:not(.workflow-layout):not(.settings-layout):not(.tool-layout) > .workbench,
.layout:not(.workflow-layout):not(.settings-layout):not(.tool-layout) > .monitor {
  min-width: 0;
  max-width: 100%;
}

/* ============================================================
   生成类模块统一双区滚动(图片/视频/声音对称) —— 唯一来源
   三模块布局都是「左参数区 .workbench + 右任务区 .monitor」两栏。
   这里一处定义视口锁 + 双区各自独立滚动的完整 min-height:0 高度链;
   图片(batchModule)以前是裸 .layout(无视口锁/无 per-panel 滚动),视频/声音
   走 .media-tool-layout(有视口锁但 workbench/monitor 被 min-height 撑爆、任务区 genFeed
   无高度约束被 .monitor overflow:hidden 裁掉)。统一收口到这一套,避免三份重复。
   选择器口径沿用本文件既有「三生成模块」写法(:is([data-module-panel=...]))。 */
#appLayout.layout:not(.workflow-layout):not(.canvas-layout):not(.settings-layout):is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) {
  /* 视口锁:整页不滚,滚动落到左右两区内部。视频/声音已由 .media-tool-layout 设过,
     图片此前缺失,在此补齐使三者对称。 */
  height: 100vh;
  min-height: 0;
  overflow: hidden;
}

/* 图片的“生图/改图”与生成媒体库组成一个连续工作区：两块面板的边界本身就是分隔，
   桌面端不再额外留出栅格列缝。只收紧 column-gap，保留通用 row-gap 与手机横向分页布局。 */
@media (min-width: 821px) {
  #appLayout.layout[data-module-panel="batchModule"] {
    --layout-column-gap: 0px;
  }
}

#appLayout.layout:not(.workflow-layout):not(.canvas-layout):not(.settings-layout):is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .workbench,
#appLayout.layout:not(.workflow-layout):not(.canvas-layout):not(.settings-layout):is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .monitor {
  /* 高度链:面板填满栅格格子且可收缩(min-height:0),内部内容才能溢出并触发滚动条;
     若 min-height 被撑到 100vh 就会比格子高、把自身滚动顶没、底部被视口锁裁掉(本次回归根因)。 */
  min-height: 0;
  height: 100%;
  max-height: 100%;
}

#appLayout.layout:not(.workflow-layout):not(.canvas-layout):not(.settings-layout):is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .workbench {
  /* 左参数区独立竖向滚动；隐藏滚动条但保留滚动(更干净好看) */
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* 旧 Edge/IE */
}
#appLayout.layout:not(.workflow-layout):not(.canvas-layout):not(.settings-layout):is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .workbench::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none; /* Chrome/Safari/新 Edge */
}

/* feed 模式(图片/视频/声音任务区都用 genFeed 画廊):
   让 .monitor 内部成为弹性列,画廊 #genFeed 充满剩余高度并自身滚动,
   在 .monitor overflow:hidden 内部滚,而不是被裁掉。 */
#appLayout.layout:is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .monitor.feed-mode {
  display: flex;
  flex-direction: column;
}
#appLayout.layout:is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .monitor.feed-mode .monitor-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
#appLayout.layout:is([data-module-panel="batchModule"], [data-module-panel="videoModule"], [data-module-panel="audioModule"]) > .monitor.feed-mode #genFeed.gen-feed {
  flex: 1 1 auto;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
}

.tabs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-bottom: 1px solid var(--border);
}

.tab {
  border: 0;
  border-right: 1px solid var(--border);
  background: #f9fafc;
  color: var(--muted);
  padding: 14px 12px;
  cursor: pointer;
}

.tab:last-child {
  border-right: 0;
}

.tab.active {
  background: #ffffff;
  color: var(--text);
  font-weight: 700;
  box-shadow: inset 0 -3px 0 var(--accent);
}

.tab-panel {
  display: none;
  padding: 18px;
}

.tab-panel.active {
  display: block;
}

#imageTab .drop-zone p {
  overflow-wrap: anywhere;
}

#imageTab .command-row.compact {
  max-width: 100%;
}

.module-workflow-panel {
  display: none;
}

.layout.workflow-layout,
.layout.canvas-layout {
  grid-template-columns: minmax(0, 1fr);
  /* 锁定到视口高度、不让整页滚动（与 .media-tool-layout 同一套做法）。
     呼吸边距沿用布局自带的 padding(--layout-padding) + workbench 卡片内边距，不再清零。 */
  height: 100vh;
  min-height: 0;
  overflow: hidden;
}

/* workbench/画布面板/外壳/主区改用 100% 高度链填满锁定后的视口，替代旧的 calc(100vh - 魔法数)。
   workbench 是最外面那张大卡片(边框/圆角保留)，但内边距清零(高优先级压过 .panel 的 padding)，
   让画布网格直接拉满到大卡片内沿、不再在里面套一层小长方形。呼吸感只由最外层 --layout-padding 给。 */
body:not(.auth-required) .layout.canvas-layout > .workbench,
body:not(.auth-required) .layout.workflow-layout > .workbench {
  height: 100%;
  min-height: 0;
  /* !important 仅为压过源码里 :where(.workbench…){padding:..!important} 那条强制内边距，
     好让画布拉满到大卡片内沿；这是对账既有 !important，不再叠新的局部层。 */
  padding: 0 !important;
}
.layout.canvas-layout .infinite-canvas-panel,
.layout.workflow-layout .module-workflow-panel {
  height: 100%;
  min-height: 0;
  padding: 0;
}

.layout.workflow-layout .monitor,
.layout.canvas-layout .monitor,
.layout.settings-layout .monitor,
.layout.tool-layout:not(.media-tool-layout) .monitor,
.layout.tools-layout .monitor {
  display: none;
}

.layout.canvas-layout,
.layout.settings-layout,
.layout.tools-layout,
.layout.tool-layout:not(.media-tool-layout) {
  grid-template-columns: minmax(0, 1fr);
}

.layout.media-tool-layout {
  grid-template-columns: minmax(420px, 0.78fr) minmax(0, 1.22fr);
  height: 100vh;
  min-height: 0;
  overflow: hidden;
}

.layout.media-tool-layout .workbench,
.layout.media-tool-layout .monitor {
  min-height: calc(100vh - (var(--layout-padding) * 2));
  height: 100%;
}

.layout.media-tool-layout,
.layout.media-tool-layout .workbench,
.layout.media-tool-layout .monitor,
.layout.media-tool-layout .tool-panel,
.layout.media-tool-layout .tool-grid,
.layout.media-tool-layout .tool-card,
.layout.media-tool-layout .form-grid,
.layout.media-tool-layout .options-grid,
.layout.media-tool-layout .advanced,
.layout.media-tool-layout label,
.layout.media-tool-layout input,
.layout.media-tool-layout select,
.layout.media-tool-layout textarea {
  box-sizing: border-box;
  min-width: 0;
  max-width: 100%;
}

.layout.media-tool-layout > .panel {
  min-height: 0;
}

.layout.media-tool-layout .workbench {
  overflow-x: hidden;
  overflow-y: auto;
}

.layout.canvas-layout .tabs,
.layout.settings-layout .tabs,
.layout.tool-layout .tabs {
  display: none;
}

/* 音乐模式 tabs 复用全站 .tabs 样式(与图片模块同款),要从上面这条「工具布局隐藏主 tabs」里豁免出来 */
.layout.tool-layout #musicModeTabs.tabs {
  display: grid;
}

.layout.media-tool-layout .tool-grid {
  grid-template-columns: 1fr;
}

.layout.media-tool-layout .media-debug-card {
  display: none;
}

.layout.media-tool-layout .tool-panel.active {
  padding: var(--panel-padding);
  min-height: 100%;
}

.layout.media-tool-layout .tool-page-head {
  margin: calc(var(--panel-padding) * -1) calc(var(--panel-padding) * -1) var(--panel-padding);
  min-height: var(--tab-height);
  padding: 0 var(--panel-padding);
  border-bottom: 1px solid var(--border);
  background: #f9fafc;
  align-items: center;
}

.layout.media-tool-layout .tool-page-head h2 {
  font-size: 14px;
  line-height: 1.2;
}

.layout.media-tool-layout .tool-page-head p {
  display: none;
}

.layout.media-tool-layout .tool-card {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  box-shadow: none;
}

.layout.media-tool-layout .form-grid {
  grid-template-columns: minmax(0, 1fr) 144px;
}

.layout.media-tool-layout .quick-options {
  grid-template-columns: minmax(176px, 1.4fr) minmax(112px, 0.8fr) minmax(112px, 0.8fr);
}

.layout.media-tool-layout .advanced .options-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.layout.media-tool-layout .advanced > label {
  margin: 0 14px 14px;
}

.layout.media-tool-layout #videoToolTab .quick-options {
  grid-template-columns: minmax(176px, 1.35fr) minmax(96px, 0.75fr) minmax(96px, 0.75fr) minmax(84px, 0.65fr);
}

.layout.media-tool-layout #audioToolTab .quick-options {
  grid-template-columns: minmax(176px, 1.4fr) minmax(112px, 0.8fr) minmax(112px, 0.8fr);
}

.tool-mode-tabs[hidden] { display: none !important; } /* hidden 属性的 UA display:none 会被下面的 display:grid 覆盖,显式补回(语音功能下线用) */
.tool-mode-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin: 0 0 var(--panel-padding);
  padding: 6px;
  border: 1px solid #dce6ef;
  border-radius: 16px;
  background: #f4f8fb;
}

.layout.media-tool-layout #audioToolTab {
  padding-top: 0;
}

.layout.media-tool-layout #audioToolTab > .tool-mode-tabs {
  margin: 0 calc(var(--panel-padding) * -1) var(--panel-padding);
  border-top: 0;
  border-left: 0;
  border-right: 0;
  border-radius: 0;
}

.layout.media-tool-layout #audioToolTab > .tool-page-head {
  display: none;
}

.tool-mode-tab {
  min-height: var(--tab-height);
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: #475569;
  font-weight: 900;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, box-shadow 0.14s ease;
}

.tool-mode-tab:hover {
  background: rgba(255, 255, 255, 0.76);
  color: #344054;
}

.tool-mode-tab.active {
  background: #ffffff;
  color: #0f172a;
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.08), inset 0 -2px 0 #2f6db7;
}

.audio-mode-panel {
  display: none;
}

.audio-mode-panel.active {
  display: block;
}

.layout.media-tool-layout #audioToolTab .music-options {
  grid-template-columns: minmax(176px, 1.4fr) minmax(120px, 0.8fr);
}

.compact-checkbox {
  min-height: 62px;
  justify-content: center;
}

.compact-checkbox input {
  width: auto;
}

.layout.tool-layout:not(.media-tool-layout) .tool-panel {
  width: 100%;
  max-width: none;
  height: calc(100vh - 34px);
  padding: 12px;
}

.tab-panel.settings-panel {
  display: none;
}

.tab-panel.settings-panel.active {
  max-width: 1180px;
  display: grid;
  gap: 14px;
}

.settings-panel > label:first-child,
.settings-panel > .form-grid,
.settings-panel > .options-grid,
.settings-panel > .key-manager,
.settings-panel > .toggle-row,
.settings-panel > .command-row,
.settings-panel > .result-box {
  margin-bottom: 0;
}

.settings-panel > label:first-child,
.settings-panel > .form-grid,
.settings-panel > .options-grid {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 14px;
}

.settings-panel > .form-grid {
  grid-template-columns: minmax(260px, 1.15fr) minmax(220px, 0.85fr) minmax(260px, 1fr);
  align-items: end;
}

.settings-panel > .options-grid {
  margin: 0;
}

.tool-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.tool-page-head p {
  color: var(--muted);
  margin-top: 5px;
}

.tool-grid {
  display: grid;
  grid-template-columns: minmax(360px, 0.95fr) minmax(360px, 1.05fr);
  gap: 14px;
}

.tool-grid-balanced {
  grid-template-columns: minmax(420px, 1.05fr) minmax(360px, 0.95fr);
}

.tool-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 14px;
  display: grid;
  gap: 14px;
  align-content: start;
}

.tool-card .form-grid,
.tool-card .options-grid,
.tool-card .quick-options {
  margin-top: 0;
  margin-bottom: 0;
}

.tool-card h2 {
  font-size: 16px;
}

.tool-result-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.tool-result-text {
  min-height: 420px;
  background: #ffffff;
}

.text-chat-shell {
  display: grid;
  grid-template-columns: 284px minmax(0, 1fr);
  width: 100%;
  height: 100%;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: #ffffff;
  box-shadow: 0 12px 36px rgba(26, 32, 44, 0.06);
}

.text-chat-sidebar {
  display: grid;
  grid-template-rows: auto auto auto minmax(0, 1fr);
  gap: 10px;
  min-height: 0;
  padding: 14px 12px;
  border-right: 1px solid var(--border);
  background: #f7fbff;
}

.text-chat-brand {
  display: grid;
  gap: 5px;
  padding: 2px 4px 4px;
}

.text-chat-brand strong {
  color: var(--text);
  font-size: 18px;
  font-weight: 800;
}

.text-chat-brand span {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.text-new-chat-btn {
  min-height: 36px;
}

.text-chat-search-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: stretch;
}

.text-chat-search {
  min-width: 0;
}

.text-chat-search input {
  height: 38px;
  border-radius: 8px;
  background: #ffffff;
}

.text-chat-history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  padding: 2px 4px 0;
}

.text-chat-history-head small {
  color: #94a3b8;
  font-size: 12px;
  font-weight: 650;
}

.text-chat-history-head-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.text-chat-history-close {
  display: none;
}

.text-chat-history {
  display: grid;
  align-content: start;
  gap: 8px;
  min-height: 0;
  overflow: auto;
  padding: 2px 4px 4px 0;
}

.text-chat-history-item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 52px;
  align-items: stretch;
  gap: 9px;
  min-height: 72px;
  padding: 10px 10px 10px 12px;
  border: 1px solid #dce7f3;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.82), 0 6px 16px rgba(47, 109, 183, 0.04);
  text-align: left;
  overflow: hidden;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.text-chat-history-item::before {
  content: "";
  position: absolute;
  top: 11px;
  bottom: 11px;
  left: 0;
  width: 3px;
  border-radius: 0 999px 999px 0;
  background: transparent;
  transition: background 0.15s ease;
}

.text-chat-history-item:hover {
  border-color: #b9d1ec;
  background: #f8fbff;
  box-shadow: 0 10px 22px rgba(47, 109, 183, 0.075);
}

.text-chat-history-item.active {
  border-color: #9fc3ea;
  background: #eef6ff;
  box-shadow: 0 10px 22px rgba(47, 109, 183, 0.105);
}

.text-chat-history-item.active::before {
  background: var(--accent);
}

.text-chat-history-main {
  display: grid;
  align-content: center;
  gap: 7px;
  min-width: 0;
  border-radius: 6px;
  cursor: pointer;
  user-select: none;
}

.text-chat-history-main:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.16);
}

.text-chat-history-main strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
  font-size: 13px;
  font-weight: 800;
  line-height: 1.24;
}

.text-chat-history-item.renaming {
  border-color: var(--accent);
  background: #f5f9fd;
}

.text-chat-history-main.renaming {
  cursor: text;
}

.text-chat-history-main strong[contenteditable="true"] {
  min-width: 0;
  padding: 2px 5px;
  border: 1px solid #b9cfe8;
  border-radius: 5px;
  background: #ffffff;
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.1);
  cursor: text;
  outline: none;
  user-select: text;
}

.text-chat-history-subline {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.text-chat-history-preview {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.text-chat-history-count {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 20px;
  padding: 0 6px;
  border: 1px solid #d8e6f6;
  border-radius: 999px;
  background: #eef5ff;
  color: var(--accent);
  font-size: 11px;
  font-weight: 760;
  line-height: 1;
}

.text-chat-history-meta {
  display: grid;
  align-content: center;
  justify-items: end;
  gap: 8px;
  min-width: 0;
}

.text-chat-history-meta time {
  color: #94a3b8;
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
}

.text-chat-delete-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 28px;
  min-height: 28px;
  max-height: 28px;
  padding: 0 9px;
  border: 1px solid #cfe0f4;
  border-radius: 999px;
  background: rgba(247, 251, 255, 0.78);
  color: #4f7fb5;
  font-size: 11px;
  font-weight: 760;
  line-height: 1;
  appearance: none;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.text-chat-delete-btn:hover {
  border-color: #e8c4be;
  background: #fff7f6;
  color: #b42318;
  box-shadow: 0 6px 14px rgba(180, 35, 24, 0.08);
}

.text-chat-history-item.active .text-chat-delete-btn {
  border-color: #c5dbf4;
  background: rgba(255, 255, 255, 0.78);
  color: #2f6db7;
}

.text-chat-history-item.active .text-chat-delete-btn:hover {
  border-color: #e8c4be;
  background: #fff7f6;
  color: #b42318;
  box-shadow: 0 6px 14px rgba(180, 35, 24, 0.08);
}

.text-chat-empty-mini {
  padding: 14px 10px;
  color: var(--muted);
  text-align: center;
  border: 1px dashed #cbd5e1;
  border-radius: 8px;
  background: #ffffff;
}

.text-chat-main {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  container-type: inline-size;
  min-height: 0;
  min-width: 0;
  background: #ffffff;
}

.text-chat-topbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  background: #ffffff;
}

.text-chat-current {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.text-chat-current strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 16px;
  font-weight: 800;
}

.text-chat-current span {
  color: var(--muted);
  font-size: 12px;
}

.text-chat-modelbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
  padding: 0;
}

.text-chat-modelbar > label:not(.switch-row) {
  width: min(340px, 42vw);
  margin: 0;
}

.switch-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-content: center;
  min-height: 32px;
  height: 32px;
  min-width: 76px;
  padding: 0 9px;
  border: 1px solid #d8e1ec;
  border-radius: 8px;
  background: #f8fafc;
  color: var(--text);
  font-weight: 650;
  white-space: nowrap;
  font-size: 12px;
}

.switch-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  min-width: 18px;
  margin: 0;
  accent-color: var(--accent);
}

.text-chat-messages {
  display: flex;
  flex-direction: column;
  align-content: start;
  gap: 16px;
  min-height: 0;
  padding: 26px min(5vw, 58px);
  overflow: auto;
  background:
    linear-gradient(180deg, #f8fbfa 0, rgba(255, 255, 255, 0.96) 180px),
    #ffffff;
}

.text-chat-empty {
  align-self: center;
  display: grid;
  gap: 14px;
  width: min(620px, 100%);
  margin-top: min(12vh, 96px);
  padding: 28px;
  border: 1px solid #dbe5ef;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 12px 30px rgba(26, 32, 44, 0.06);
}

.text-chat-empty strong {
  font-size: 20px;
  font-weight: 800;
}

.text-chat-empty p {
  color: var(--muted);
  line-height: 1.55;
}

.text-chat-suggestions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.text-chat-suggestions button {
  min-height: 38px;
  border: 1px solid #a9c8e8;
  border-radius: 8px;
  background: #eaf2fb;
  color: var(--accent-strong);
  cursor: pointer;
  text-align: left;
  padding: 8px 10px;
}

.text-chat-suggestions button:hover {
  border-color: var(--accent);
  background: #ddebf9;
}

.text-chat-message {
  display: flex;
  gap: 10px;
  max-width: min(820px, 88%);
}

.text-chat-message.user {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.text-chat-message.assistant,
.text-chat-message.system {
  align-self: flex-start;
}

.text-chat-avatar {
  display: grid;
  place-items: center;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  margin-top: 18px;
  border-radius: 8px;
  background: #eaf2fb;
  color: #2f6db7;
  font-size: 12px;
  font-weight: 800;
}

.text-chat-message.user .text-chat-avatar {
  background: var(--accent);
  color: #ffffff;
}

.text-chat-content {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.text-chat-role {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  padding: 0 2px;
}

/* 用户消息:头像已是「你」,角色标签「你」重复 → 隐藏标签并让头像与气泡顶对齐 */
.text-chat-message.user .text-chat-role {
  display: none;
}

.text-chat-message.user .text-chat-avatar {
  margin-top: 0;
}

.text-chat-bubble {
  white-space: pre-wrap;
  word-break: break-word;
  border: 1px solid #d9e1ea;
  border-radius: 8px;
  padding: 13px 15px;
  background: #ffffff;
  color: var(--text);
  line-height: 1.72;
  box-shadow: 0 8px 22px rgba(28, 38, 54, 0.055);
}

.text-chat-bubble-wrap {
  display: grid;
  gap: 6px;
  justify-items: start;
}

.text-chat-message.user .text-chat-bubble-wrap {
  justify-items: end;
}

.text-message-copy {
  min-height: 26px;
  padding: 4px 8px;
  border: 1px solid #cbd8e6;
  border-radius: 6px;
  background: #ffffff;
  color: #386097;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}

.text-message-copy:hover {
  border-color: #9bb7d8;
  background: #f4f8fd;
}

.text-chat-message.user .text-chat-bubble {
  border-color: #9fc3e8;
  background: #eaf2fb;
  box-shadow: 0 6px 18px rgba(47, 109, 183, 0.08);
}

.text-chat-message.system .text-chat-bubble {
  background: #f1f5f9;
  color: var(--muted);
}

.text-chat-footer {
  display: grid;
  gap: 10px;
  min-width: 0;
  padding: 12px min(4vw, 42px) 14px;
  border-top: 1px solid var(--border);
  background: #ffffff;
}

.text-chat-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
  align-items: end;
  min-width: 0;
  grid-column: 2;
  grid-row: 1;
}

.text-chat-tools button,
.text-chat-modelbar button {
  min-height: 32px;
  height: 32px;
  padding: 6px 10px;
  border-radius: 7px;
  font-size: 12px;
}

.text-chat-tools .secondary,
.text-chat-tools .danger,
.text-chat-modelbar .secondary {
  padding-inline: 9px;
}

.text-chat-modelbar select {
  min-height: 32px;
  height: 32px;
  padding: 6px 10px;
  border-radius: 7px;
  font-size: 13px;
}

.text-chat-composer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: end;
  min-width: 0;
  padding: 9px;
  border: 1px solid #cbd8e6;
  border-radius: 8px;
  background: #fbfcfe;
  box-shadow: 0 8px 24px rgba(26, 32, 44, 0.06);
  grid-column: 1 / -1;
  grid-row: 2;
}

.text-chat-composer textarea {
  min-height: 50px;
  max-height: 180px;
  resize: none;
  border: 0;
  padding: 10px;
  background: transparent;
  box-shadow: none;
}

.text-chat-composer .primary {
  min-width: 72px;
  min-height: 38px;
  padding: 8px 14px;
  align-self: end;
}

.text-chat-footer {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
}

.text-chat-topbar .text-chat-modelbar {
  grid-column: 2;
  grid-row: 1;
}

.text-chat-modelbar > label:not(.switch-row) {
  display: grid;
  grid-template-columns: auto minmax(220px, 1fr);
  align-items: center;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
}

.text-chat-model-label {
  white-space: nowrap;
}

.text-chat-modelbar > label:not(.switch-row) select {
  min-width: 220px;
}

@container (max-width: 560px) {
  .text-chat-footer {
    grid-template-columns: minmax(0, 1fr);
    align-items: stretch;
    padding-inline: 14px;
  }

  .text-chat-tools {
    grid-column: 1;
    grid-row: 1;
    justify-content: flex-end;
  }

  .text-chat-modelbar {
    grid-column: 1;
    grid-row: 2;
    justify-content: flex-start;
  }

  .text-chat-modelbar > label:not(.switch-row) {
    width: 100%;
    grid-template-columns: auto minmax(0, 1fr);
  }

  .text-chat-modelbar > label:not(.switch-row) select {
    min-width: 0;
    width: 100%;
  }

  .text-chat-composer {
    grid-column: 1;
    grid-row: 3;
  }
}

.light-result {
  background: #ffffff;
  color: var(--text);
  border: 1px solid var(--border);
  min-height: 420px;
}

label {
  display: grid;
  gap: 7px;
  color: #344054;
  font-weight: 650;
}

input,
select,
textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: var(--control-padding-y) var(--control-padding-x);
  background: #ffffff;
  color: var(--text);
  outline: none;
}

input[type="number"] {
  padding-right: 6px;
  appearance: auto;
  -webkit-appearance: auto;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  opacity: 1;
  margin: 0;
  cursor: pointer;
}

input:disabled,
select:disabled,
textarea:disabled {
  background: #f2f4f7;
  border-color: #d5dbe5;
  color: #7b8798;
  cursor: not-allowed;
  opacity: 1;
}

input.fixed-duration:disabled,
select.fixed-duration:disabled {
  background: #eef1f5;
  color: #667085;
}

textarea {
  min-height: 132px;
  resize: vertical;
  line-height: 1.48;
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.14);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 144px;
  gap: var(--form-gap);
  margin-bottom: var(--section-gap);
}

.options-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(120px, 1fr));
  gap: calc(15px * var(--ui-density));
  margin: var(--section-gap) 0;
}

.ark-model-panel {
  border: 1px solid #a9c8e8;
  border-radius: 8px;
  background: #f6fbf8;
  padding: 14px;
  margin: 12px 0 14px;
}

.model-category-panel {
  display: grid;
  grid-template-columns: repeat(2, minmax(360px, 1fr));
  gap: 12px;
  margin: 0;
}

.model-category-card {
  border: 1px solid #c7d8ea;
  border-radius: 8px;
  background: #ffffff;
  padding: 14px;
  display: grid;
  gap: 12px;
  box-shadow: 0 8px 22px rgba(15, 23, 42, 0.05);
}

.model-category-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: flex-start;
  border-bottom: 1px solid #e5eee9;
  padding-bottom: 10px;
}

.model-category-head strong {
  display: block;
  color: var(--accent-strong);
  font-size: 15px;
}

.model-category-head span {
  display: block;
  color: var(--muted);
  font-size: 12px;
  margin-top: 3px;
}

.model-category-fields {
  display: grid;
  grid-template-columns: minmax(180px, 0.9fr) minmax(220px, 1.1fr);
  gap: 10px;
  align-items: end;
}

.model-category-fields label:last-child {
  grid-column: 1 / -1;
}

.model-category-note {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
  min-height: 34px;
}

.model-category-key-manager {
  border: 1px solid #d7e2ef;
  border-radius: 8px;
  background: #f8fbfa;
  padding: 10px;
  display: grid;
  gap: 10px;
}

.model-category-key-head {
  display: grid;
  gap: 3px;
}

.model-category-key-head strong {
  color: var(--accent-strong);
  font-size: 13px;
}

.model-category-key-head span {
  color: var(--muted);
  font-size: 12px;
}

.category-key-add-row,
.category-key-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 74px;
  gap: 8px;
  align-items: center;
}

.category-key-row {
  grid-template-columns: 28px minmax(180px, 1fr) 64px 64px;
}

.category-key-list {
  display: grid;
  gap: 8px;
}

.model-category-status {
  min-height: 18px;
  color: var(--muted);
  font-size: 12px;
  white-space: pre-wrap;
  border-radius: 6px;
  background: #f8fafc;
  border: 1px dashed #d6dee8;
  padding: 8px 10px;
}

.model-category-status.ok {
  color: var(--ok);
  background: #f3faf6;
  border-color: #a9c8e8;
}

.model-category-status.error {
  color: var(--danger);
  background: #fff7f7;
  border-color: #f0b7b7;
}

.ark-model-panel-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.ark-model-panel-head strong {
  display: block;
  color: var(--accent-strong);
  font-size: 15px;
  margin-bottom: 3px;
}

.ark-model-panel-head span {
  color: #5c728a;
  font-size: 13px;
}

.ark-model-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px;
}

.ark-model-card {
  display: grid;
  gap: 10px;
  align-content: start;
  border: 1px solid #cfe0f0;
  border-radius: 8px;
  background: #ffffff;
  padding: 12px;
}

.ark-model-card.active {
  border-color: #2f6db7;
  box-shadow: 0 0 0 2px rgba(47, 109, 183, 0.12);
}

.ark-model-card strong {
  color: #1d4a83;
  font-size: 14px;
}

.ark-model-card small {
  color: #5e7180;
  line-height: 1.45;
}

.ark-model-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ark-model-status {
  min-height: 18px;
  color: #5e7180;
  font-size: 12px;
  white-space: pre-wrap;
}

.ark-model-status.ok {
  color: #2563a7;
}

.ark-model-status.error {
  color: var(--danger);
}

.quick-options {
  grid-template-columns: minmax(144px, 1.4fr) minmax(96px, 0.8fr) minmax(96px, 0.8fr);
  margin: var(--section-gap) 0;
}

.toggle-row {
  color: var(--muted);
  margin: 8px 0 16px;
}

.advanced {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fbfcfe;
  margin: var(--section-gap) 0;
  padding: 0;
}

.advanced summary {
  cursor: pointer;
  padding: 12px 14px;
  font-weight: 760;
  color: #344054;
}

.advanced .form-grid,
.advanced .options-grid,
.advanced .toggle-row {
  margin-left: 14px;
  margin-right: 14px;
}

/* 「高级参数」下拉里的字段网格统一两列：图片/文生图走通用布局会继承基础 .options-grid 的 4 列，
   而视频/音频走 media-tool-layout 是 2 列，导致同一个「高级参数」栏目在各工具里排布、高度都不一样。
   这里在源头把所有工具的高级参数字段网格固定成 2 列，media-tool-layout 的同名规则随之变成等值冗余。 */
.advanced .options-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.advanced .form-grid {
  padding-top: 2px;
}

.toggle-row label {
  display: flex;
  grid-template-columns: none;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.toggle-row input {
  width: auto;
}

button,
.button-link {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #ffffff;
  color: var(--text);
  padding: var(--button-padding-y) var(--button-padding-x);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--button-height);
}

button:hover,
.button-link:hover {
  border-color: #aeb7c6;
}

button:disabled,
.disabled {
  opacity: 0.46;
  pointer-events: none;
}

.topbar .module-tab {
  display: grid;
  grid-template-rows: 20px 18px;
  align-content: center;
  align-items: center;
  justify-content: stretch;
  justify-items: start;
  min-height: 68px;
  text-align: left;
}

.topbar .module-tab strong,
.topbar .module-tab span {
  justify-self: start;
  text-align: left;
}

body.sidebar-collapsed .topbar .module-tab {
  grid-template-rows: 1fr;
  justify-items: center;
  min-height: 48px;
  text-align: center;
}

body.sidebar-collapsed .topbar .module-tab strong,
body.sidebar-collapsed .topbar .module-tab span {
  display: none;
}

.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
  font-weight: 760;
}

.primary:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}

.secondary {
  color: #45546b;
  border-color: var(--border);
  background: #ffffff;
}

.secondary:hover {
  color: var(--text);
  border-color: #c6d2e2;
  background: var(--surface-3);
}

.danger {
  color: var(--danger);
  border-color: #f0b8b2;
  background: #fff8f7;
}

.danger.confirming {
  color: #ffffff;
  border-color: var(--danger);
  background: var(--danger);
}

.icon-button {
  min-width: 88px;
}

.file-picker {
  margin-bottom: 8px;
}

.hidden-input {
  display: none;
}

[hidden] {
  display: none !important;
}

/* 参考区外层不再画一圈虚线框（那个「奇怪的底层」），只留标签头部 + 「点击选择参考图」选择框。
   tap-highlight 透明：点标签/头部不再闪蓝。 */
.upload-box {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  display: grid;
  gap: 8px;
  margin-bottom: var(--section-gap);
  -webkit-tap-highlight-color: transparent;
}

.drop-zone {
  border: 1px dashed #9aa8bb;
  border-radius: 8px;
  background: #fbfcfe;
  padding: var(--section-gap);
  margin-bottom: 10px;
  display: grid;
  gap: 8px;
}

.upload-box .drop-zone {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0;
  margin-bottom: 0;
}

/* 不再整框变蓝；拖拽高亮只落在「点击选择参考图」选择框(#xxxFileSummary)上。 */
.upload-box:has(.drop-zone.drag-over) {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}

.drop-zone.drag-over {
  border-color: var(--accent);
  background: #eef7f3;
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.12);
}

.upload-box .drop-zone.drag-over {
  background: transparent;
  box-shadow: none;
}

.drop-zone strong {
  font-size: 15px;
}

.drop-zone p {
  color: var(--muted);
  line-height: 1.45;
}

.text-ref-drop-zone {
  margin-bottom: 10px;
}

.text-ref-drop-zone .compact {
  margin-bottom: 0;
}

.file-summary {
  border: 1px dashed #bcc5d3;
  border-radius: 6px;
  color: var(--muted);
  background: #fbfcfe;
  padding: 12px;
  margin-bottom: 14px;
}

.upload-box .file-summary {
  margin-bottom: 0;
  background: #ffffff;
}

.upload-box .file-summary[hidden] {
  display: none !important;
}

.upload-box .file-summary-empty {
  color: #66758a;
  background: rgba(255, 255, 255, 0.78);
  border-color: #c8d7e8;
}

.upload-box .selected-preview {
  margin: 0;
}

.plan-summary-inline {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  flex: 1 1 220px;
  border: 1px dashed #bcc5d3;
  border-radius: 6px;
  color: var(--muted);
  background: #fbfcfe;
  padding: 9px 12px;
  line-height: 1.35;
}

.model-capability-hint {
  margin: -4px 0 14px;
  min-height: 34px;
  border: 1px dashed #c8d9ec;
  border-radius: 6px;
  background: #f2f7fb;
  color: #2f5e88;
  padding: 8px 10px;
  font-size: 13px;
  line-height: 1.35;
}
/* 管理员:模型介绍可双击编辑(实线边框 + 文本光标提示可点) */
.model-capability-hint.capability-note-editable { cursor: text; }
.model-capability-hint.capability-note-editable:hover { border-style: solid; border-color: #9cc0e6; }
.model-capability-hint .capability-note-extra { opacity: 0.82; }
.model-capability-hint.capability-note-editing { cursor: default; }
.capability-note-editor {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 76px;
  font: inherit;
  color: #1f3d5c;
  border: 1px solid #9cc0e6;
  border-radius: 6px;
  padding: 6px 8px;
  background: #fff;
}
.capability-note-actions { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.capability-note-btn {
  font-size: 12px;
  padding: 4px 12px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid #c8d9ec;
  background: #fff;
  color: #2f5e88;
  line-height: 1.4;
}
.capability-note-btn.capability-note-save { background: #2f6fe0; border-color: #2f6fe0; color: #fff; }
.capability-note-btn.capability-note-reset { color: #b23a58; }

/* 模型能力提示现在统一放在每个工具的最下面(「生成」按钮行之后)，留出与按钮的间距。 */
.command-row + .model-capability-hint {
  margin-top: 10px;
  margin-bottom: 2px;
}

label.is-disabled {
  opacity: 0.58;
}

label.is-disabled input,
label.is-disabled select {
  cursor: not-allowed;
}

.key-manager {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fbfcfe;
  padding: 14px;
  margin-bottom: 14px;
}

.key-add-row {
  grid-template-columns: 1fr 120px;
  margin-bottom: 10px;
}

.key-add-actions {
  display: flex;
  align-items: end;
}

.key-list {
  display: grid;
  gap: 8px;
}

.key-empty {
  color: var(--muted);
  border: 1px dashed #bcc5d3;
  border-radius: 6px;
  padding: 10px;
  background: #ffffff;
}

.key-row {
  display: grid;
  grid-template-columns: 34px minmax(180px, 1fr) auto auto;
  gap: 8px;
  align-items: center;
}

.key-index {
  color: var(--muted);
  font-weight: 750;
  text-align: center;
}

.key-row input {
  font-family: Consolas, "Microsoft YaHei", monospace;
  font-size: 13px;
}

.media-output-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 12px;
  display: grid;
  gap: 7px;
}

.media-output-card strong {
  color: var(--text);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.media-output-card span {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.media-output-link {
  justify-self: start;
  text-decoration: none;
}

.media-preview-panel {
  width: min(1380px, calc(100vw - 40px)) !important;
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.media-preview-stage {
  min-height: 0;
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #f8fafc;
  padding: 14px;
}

.media-preview-stage.is-video {
  min-height: 0;
  flex: 1 1 auto;
  padding: 10px;
  overflow: hidden;
  height: auto;
}

.media-video-player {
  width: 100%;
  min-height: 0;
  flex: 1 1 auto;
  display: grid;
  grid-template-rows: minmax(220px, 1fr);
  gap: 0;
}

.media-preview-tools {
  width: min(520px, 100%);
  display: grid;
  grid-template-columns: auto minmax(130px, 220px) auto;
  gap: 10px;
  align-items: center;
}

.media-preview-viewport {
  width: 100%;
  height: min(68dvh, calc(100dvh - 330px));
  max-height: min(68dvh, calc(100dvh - 330px));
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  cursor: default;
  touch-action: none;
  padding: 4px;
}

.media-preview-viewport.zoomed {
  cursor: grab;
}

.media-preview-viewport.dragging {
  cursor: grabbing;
}

.media-preview-stage.is-video .media-preview-viewport {
  width: 100%;
  height: 100%;
  max-height: none;
  position: relative;
  padding: 0;
  border-radius: 8px;
  background: #0f172a;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.media-preview-stage video {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  box-sizing: border-box;
  object-fit: contain;
  border-radius: 8px;
  background: #0f172a;
  transform-origin: center center;
  will-change: transform;
  box-shadow: 0 18px 46px rgba(15, 23, 42, 0.16);
}

.media-preview-stage.is-video video {
  position: static;
  inset: auto;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  display: block;
  object-fit: contain;
  box-shadow: none;
}

.media-video-controls {
  display: grid;
  grid-template-columns: auto auto minmax(180px, 1fr);
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid rgba(47, 103, 178, 0.18);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.08);
}

.media-video-play {
  min-width: 72px;
}

.media-video-time {
  color: #334155;
  font-size: 13px;
  font-weight: 780;
  white-space: nowrap;
}

.media-video-progress {
  width: 100%;
  min-width: 0;
}

.audio-preview-box {
  width: min(680px, 100%);
  display: grid;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
}

.audio-preview-box audio {
  width: 100%;
}

.selected-preview {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 8px;
  max-height: 220px;
  overflow: auto;
  margin: -4px 0 14px;
}

.selected-thumb {
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: #ffffff;
  min-width: 0;
  position: relative;
}

.selected-thumb.reused {
  border-color: #84aed6;
}

.selected-thumb.draggable {
  cursor: grab;
}

/* 拖动中的参考图悬浮跟随光标（必须 fixed，否则相对 relative 原位偏移会“飘”） */
.selected-thumb.reference-dragging-live {
  position: fixed;
  z-index: var(--z-drag-ghost);
  margin: 0;
  pointer-events: none;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.36);
  transform: scale(1.05);
  opacity: 0.97;
  cursor: grabbing;
}

.selected-thumb.reference-dragging-live.reference-dragging-delete {
  border-color: #d9534f;
  box-shadow: 0 12px 26px rgba(217, 83, 79, 0.45);
}

/* 占位=一块**干净的空档**,不画虚线框也不上底色。
   参考图被拿起后已经脱离文档流,后面的图自然补位;这个空档跟着指针走,就是落点提示本身。
   再画一个方框就又变成「屏幕上两个一样的块」,手感发涩(用户明确要「跟真拿起来一样」)。 */
.selected-thumb.reference-drag-placeholder {
  border-color: transparent;
  background: none;
}

/* 把参考图从一个框拖到本工具的另一个框时,高亮将要放入的目标框(蓝色,区别于拖出删除的红色) */
.reference-picker.reference-drag-move-target {
  outline: 2px dashed var(--accent);
  outline-offset: -3px;
  background: rgba(47, 109, 183, 0.08) !important;
}

/* 源缩略图在拖动期间整块藏掉(不是半透明):手上已经有幽灵了,原位不该再有一个本体。
   visibility 保留几何,索引/排序计算不受影响。 */
.selected-thumb.dragging {
  visibility: hidden;
}

.selected-thumb.drag-over {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.thumb-remove {
  position: absolute;
  top: 6px;
  right: 6px;
  min-width: 0;
  padding: 4px 7px;
  border-color: rgba(185, 28, 28, 0.35);
  background: rgba(255, 255, 255, 0.92);
  color: var(--danger);
  font-size: 12px;
}

.selected-thumb img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  background: #eef1f6;
}

.selected-thumb video,
.selected-thumb .thumb-preview-plain {
  width: 100%;
  aspect-ratio: 1 / 1;
}

.selected-thumb .thumb-preview-plain {
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 0;
  padding: 0;
  background: #f7fafd;
  color: var(--text);
  overflow: hidden;
}

.selected-thumb .thumb-preview-plain video {
  object-fit: cover;
  display: block;
  background: #eef2ff;
}

.selected-thumb .media-thumb-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 999px;
  background: #eaf2fb;
  color: var(--accent);
  font-weight: 700;
  padding: 0;
}

.selected-thumb span {
  display: block;
  padding: 6px;
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-box {
  background: #101828;
  color: #d7e7ff;
  border-radius: 6px;
  padding: 12px;
  min-height: 72px;
  white-space: pre-wrap;
  overflow: auto;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.result-box.is-error,
.light-result.is-error,
.file-summary.is-error {
  border-color: #f2b8ad;
  background: #fff7f5;
  color: #9f1d1d;
}

.monitor-header {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: flex-start;
  margin-bottom: 10px;
}

.progress-wrap {
  margin-bottom: 10px;
}

.progress-meta {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  color: var(--muted);
}

.progress-bar {
  width: 0;
}

.state-pill {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 5px 8px;
  background: #eef7f3;
  color: var(--ok);
  border: 1px solid #c7d8ea;
  font-weight: 700;
}

.state-pill.neutral {
  background: #f2f4f7;
  color: #475467;
  border-color: #d0d5dd;
}

.state-pill.error {
  background: #fff1f0;
  color: var(--danger);
  border-color: #ffc9c4;
}

.state-pill.warn {
  background: #fff8eb;
  color: var(--warning);
  border-color: #ffd99a;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 10px;
}

.stats-grid div {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 9px;
  display: grid;
  gap: 4px;
  background: #fbfcfe;
}

.stats-grid span {
  font-size: 18px;
  font-weight: 800;
}

.stats-grid small {
  color: var(--muted);
}

.compact {
  margin-bottom: 14px;
}

.folder-row {
  margin: 10px 0 14px;
}

.runtime-note {
  border-color: #c7d2fe;
  background: #f8fafc;
  color: #475569;
}

.public-access #settings-output-dir {
  background: #f8fafc;
  color: #64748b;
}

.job-list {
  /* 任务与结果：方块卡片网格(自适应列数)，替代旧的细长列表行 */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  max-height: min(560px, calc(100vh - 360px));
  overflow-y: auto;
  overflow-x: hidden;
  margin-bottom: 0;
  padding-right: 4px;
  align-content: start;
  min-width: 0;
}

.job-row {
  /* 每个任务 = 一个方块卡片：上方标题+状态，下方操作 */
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel);
  padding: 10px;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.job-row:hover {
  border-color: #bfd0ea;
  box-shadow: 0 4px 14px rgba(47, 109, 183, 0.1);
}

.job-row.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 6px 18px rgba(47, 109, 183, 0.16);
}

.job-row.selected .job-select span {
  color: var(--accent-strong);
  font-weight: 700;
}

.job-select {
  text-align: left;
  width: 100%;
  background: transparent;
  border: none;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 4px;
  padding: 2px;
  min-width: 0;
  overflow: hidden;
}

.job-row-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.job-reuse,
.job-favorite {
  width: 100%;
  min-height: 34px;
  padding: 6px 8px;
}

.job-reuse,
.job-favorite,
.case-reuse,
.case-delete {
  min-width: 64px;
  color: var(--blue);
  border-color: #bfd0ea;
  background: #f7faff;
}

.job-reuse,
.job-favorite {
  min-width: 0;
}

.case-delete {
  min-width: 86px;
  color: var(--danger);
  border-color: #f1b8b2;
  background: #fff8f7;
}

.case-delete.confirming {
  color: #ffffff;
  border-color: var(--danger);
  background: var(--danger);
}

.job-row strong,
.job-select strong,
.case-select strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.job-select span {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 12px;
}

.job-select strong {
  flex: 1 1 auto;
  min-width: 0;
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}

.modal-head-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.modal-mask {
  --modal-edge: clamp(8px, 2vw, 18px);
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(15, 23, 42, 0.36);
  padding: var(--modal-edge);
  overflow: hidden;
  z-index: var(--z-modal);
}

.modal-mask[hidden] {
  display: none;
}

#accountUsageModal,
#imagePreviewModal,
#mediaPreviewModal,
#panoramaPreviewModal {
  z-index: var(--z-modal-priority);
}

body:not(.auth-required) #accountUsageModal:not([hidden]) {
  opacity: 1 !important;
}

body:not(.auth-required) #accountUsageModal:not([hidden]) .account-usage-panel {
  opacity: 1 !important;
  transform: none !important;
}

.modal-panel {
  width: min(760px, 100%);
  max-width: calc(100dvw - (var(--modal-edge) * 2));
  max-height: calc(100dvh - (var(--modal-edge) * 2));
  box-sizing: border-box;
  overflow: hidden;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 22px 60px rgba(16, 24, 40, 0.22);
  padding: 18px;
}

.app-confirm-modal {
  z-index: var(--z-modal-confirm);
  background: rgba(15, 23, 42, 0.42);
}

.app-confirm-panel {
  display: grid;
  gap: 14px;
  width: min(420px, calc(100vw - 28px));
  padding: 16px;
  border-radius: 14px;
}

.app-confirm-head strong {
  color: var(--text);
  font-size: 18px;
  font-weight: 850;
  line-height: 1.25;
}

.app-confirm-message {
  margin: 0;
  color: #475569;
  font-size: 14px;
  line-height: 1.55;
}

.app-confirm-prompt {
  display: grid;
  gap: 7px;
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 820;
}

.app-confirm-prompt input {
  width: 100%;
  min-height: 40px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  outline: none;
}

.app-confirm-prompt input:focus {
  border-color: rgba(47, 109, 183, 0.52);
  background: var(--surface);
  box-shadow: var(--focus-ring);
}

.app-confirm-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.app-confirm-actions button {
  width: 100%;
  min-height: 40px;
  border-radius: 10px;
}

.modal-panel.media-preview-panel {
  width: min(1380px, calc(100vw - 40px));
  height: min(860px, calc(100dvh - 32px));
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
}

.modal-panel.media-preview-panel.is-video-preview {
  width: min(1480px, calc(100vw - 48px));
  height: min(820px, calc(100dvh - 48px));
}

.modal-tools {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
}

.case-list {
  display: grid;
  gap: 8px;
  max-height: min(520px, calc(100vh - 180px));
  overflow: auto;
}

#caseModal.modal-mask {
  place-items: start center;
  padding-top: max(16px, min(6vh, 56px));
}

#caseModal .modal-panel {
  max-height: min(720px, calc(100dvh - 42px));
}

.case-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  align-items: stretch;
  padding: 9px;
  border: 1px solid #e2ecf4;
  border-radius: 14px;
  background: #ffffff;
}

.case-select {
  grid-column: 1 / -1;
  text-align: left;
  width: 100%;
  background: #fbfcfe;
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  min-height: 74px;
  padding: 8px;
  border-radius: 10px;
}

.case-row > button.case-reuse,
.case-row > button.case-delete {
  min-height: 34px;
  border-radius: 10px;
}

.case-info {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.case-preview {
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid #dbe7f0;
  border-radius: 8px;
  background: linear-gradient(180deg, #f8fbfd 0%, #eef6f5 100%);
  color: var(--muted);
  font-size: 13px;
  font-weight: 800;
}

.case-preview img,
.case-preview video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.case-param-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}

.case-param-list em {
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 2px 7px;
  border: 1px solid #d7e2ef;
  border-radius: 999px;
  background: #f0faf5;
  color: #2f6db7;
  font-style: normal;
  font-size: 11px;
  font-weight: 760;
}

.case-select .case-info > span:not(.case-param-list),
.empty-row {
  color: var(--muted);
}

.empty-row {
  border: 1px dashed var(--border);
  border-radius: 6px;
  padding: 14px 12px;
  background: #fbfcfe;
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.empty-row.error {
  border-color: #f2b8ad;
  background: #fff7f5;
  color: #9f1d1d;
}

.empty-row.warn {
  border-color: #f4d28a;
  background: #fffbeb;
  color: #8a5a00;
}

/* 视觉方案v1:签名式空状态——统一的原创线稿(画框+山+星芒),用 mask 着色随主题/容器自适应 */
.empty-row,
.workflow-project-empty {
  display: grid;
  justify-items: center;
  gap: 7px;
  text-align: center;
}

.empty-row::before,
.workflow-project-empty::before {
  content: "";
  width: 40px;
  height: 40px;
  background: currentColor;
  opacity: 0.4;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='6' y='11' width='28' height='24' rx='4.5'/%3E%3Cpath d='M11 29.5l6.5-7.5 5 5.5 4.5-5.5 3 3.5'/%3E%3Ccircle cx='15.5' cy='18.5' r='1.8'/%3E%3Cpath d='M40 8v7M36.5 11.5h7'/%3E%3Cpath d='M40.5 24.5l1.1 2.4 2.4 1.1-2.4 1.1-1.1 2.4-1.1-2.4-2.4-1.1 2.4-1.1z' fill='%23000' stroke='none'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='6' y='11' width='28' height='24' rx='4.5'/%3E%3Cpath d='M11 29.5l6.5-7.5 5 5.5 4.5-5.5 3 3.5'/%3E%3Ccircle cx='15.5' cy='18.5' r='1.8'/%3E%3Cpath d='M40 8v7M36.5 11.5h7'/%3E%3Cpath d='M40.5 24.5l1.1 2.4 2.4 1.1-2.4 1.1-1.1 2.4-1.1-2.4-2.4-1.1 2.4-1.1z' fill='%23000' stroke='none'/%3E%3C/svg%3E") center / contain no-repeat;
}

.gallery .empty-row {
  grid-column: 1 / -1;
}

.preview-panel {
  width: min(1280px, calc(100vw - 16px));
  height: min(860px, calc(100dvh - 24px));
  max-height: calc(100dvh - 24px);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
}

.preview-panel.is-canvas-preview {
  grid-template-rows: auto auto minmax(0, 1fr);
}

.preview-tools {
  display: grid;
  grid-template-columns: auto auto minmax(140px, 220px) auto auto auto auto;
  gap: 10px;
  align-items: center;
  margin-bottom: 12px;
}

.preview-canvas-tools[hidden] {
  display: none !important;
}

@keyframes preview-toolbar-in {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.992);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes preview-tool-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.972);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.preview-canvas-tools {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  margin: 2px 0 18px;
  padding: 7px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  border: 1px solid rgba(199, 218, 240, 0.72);
  border-radius: 20px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(246, 250, 255, 0.72)),
    rgba(247, 251, 255, 0.68);
  box-shadow:
    0 12px 32px rgba(37, 90, 156, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(16px) saturate(1.08);
  animation: preview-toolbar-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.preview-canvas-tool {
  position: relative;
  isolation: isolate;
  flex: 0 1 184px;
  min-width: 148px;
  min-height: 52px;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: center;
  gap: 9px;
  overflow: hidden;
  padding: 8px 12px 8px 8px;
  border: 1px solid transparent;
  border-radius: 15px;
  background: transparent;
  color: #102033;
  text-align: left;
  box-shadow: none;
  transform: translateY(0) scale(1);
  transition:
    transform 180ms cubic-bezier(0.16, 1, 0.3, 1),
    border-color 180ms cubic-bezier(0.16, 1, 0.3, 1),
    background 180ms cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 180ms cubic-bezier(0.16, 1, 0.3, 1),
    color 160ms ease;
}

.preview-canvas-tools:not(.is-ready) .preview-canvas-tool {
  opacity: 0;
  transform: translateY(8px) scale(0.972);
}

.preview-canvas-tools.is-ready .preview-canvas-tool {
  animation: preview-tool-in 360ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--preview-tool-index, 0) * 32ms);
}

.preview-canvas-tool::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(244, 249, 255, 0.56)),
    linear-gradient(135deg, rgba(47, 109, 183, 0.075), rgba(242, 146, 47, 0.035));
  opacity: 0.64;
  transition:
    opacity 190ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 190ms cubic-bezier(0.16, 1, 0.3, 1);
}

.preview-canvas-tool:hover {
  border-color: rgba(128, 171, 222, 0.28);
  background: transparent;
  color: #1f66b6;
  box-shadow: 0 10px 20px rgba(47, 109, 183, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.86);
  transform: translateY(-1px);
}

.preview-canvas-tool:hover::before,
.preview-canvas-tool.is-pressed::before {
  opacity: 1;
  transform: scale(0.995);
}

.preview-canvas-tool:active,
.preview-canvas-tool.is-pressed {
  transform: translateY(0) scale(0.986);
  box-shadow: 0 4px 12px rgba(47, 109, 183, 0.09), inset 0 1px 3px rgba(47, 109, 183, 0.1);
}

.preview-canvas-tool:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.preview-canvas-tool-icon {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(47, 109, 183, 0.09);
  color: #2f6db7;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.78);
  transition:
    transform 220ms cubic-bezier(0.16, 1, 0.3, 1),
    background 180ms cubic-bezier(0.16, 1, 0.3, 1),
    color 180ms cubic-bezier(0.16, 1, 0.3, 1);
}

.preview-canvas-tool:hover .preview-canvas-tool-icon {
  color: #245fa3;
  background: rgba(47, 109, 183, 0.14);
  transform: translateY(-1px) scale(1.04);
}

.preview-canvas-tool:active .preview-canvas-tool-icon,
.preview-canvas-tool.is-pressed .preview-canvas-tool-icon {
  transform: scale(0.95);
}

.preview-canvas-tool-icon svg {
  width: 17px;
  height: 17px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.85;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.preview-canvas-tool-text {
  min-width: 0;
  display: grid;
  gap: 0;
}

.preview-canvas-tool-text strong,
.preview-canvas-tool-text small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.preview-canvas-tool-text strong {
  font-size: 13.5px;
  font-weight: 860;
  line-height: 1.12;
  letter-spacing: 0;
}

.preview-canvas-tool-text small {
  color: #65758a;
  font-size: 11px;
  font-weight: 660;
  line-height: 1.14;
}

.preview-canvas-tool-text em {
  display: inline-flex;
  align-items: center;
  min-height: 16px;
  margin-left: 5px;
  padding: 0 5px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.1);
  color: #2f6db7;
  font-style: normal;
  font-weight: 900;
}

.preview-nav-btn[hidden],
.preview-counter[hidden] {
  display: none !important;
}

.preview-counter {
  min-width: 56px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
}

.preview-stage {
  min-height: 220px;
  height: auto;
  overflow: hidden;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 14px;
  cursor: default;
  user-select: none;
  touch-action: none;
}

.preview-stage.zoomed {
  cursor: grab;
}

.preview-stage.dragging {
  cursor: grabbing;
}

#previewImage {
  display: block;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  object-fit: contain;
  opacity: 0;
  transform-origin: center center;
  transition: opacity 220ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
  user-select: none;
  pointer-events: none;
}

#previewImage.preview-image-ready {
  opacity: 1;
}

#previewImage.preview-image-loading {
  opacity: 0;
}

body.theme-dark:not(.auth-required) .preview-canvas-tools {
  border-color: rgba(94, 122, 160, 0.42);
  background: rgba(18, 28, 44, 0.78);
  box-shadow: 0 16px 34px rgba(0, 0, 0, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.055);
}

body.theme-dark:not(.auth-required) .preview-canvas-tool {
  border-color: transparent;
  background: transparent;
  color: #e8eff8;
  box-shadow: none;
}

body.theme-dark:not(.auth-required) .preview-canvas-tool::before {
  background:
    linear-gradient(180deg, rgba(30, 43, 64, 0.98), rgba(20, 31, 49, 0.92)),
    linear-gradient(135deg, rgba(90, 166, 232, 0.12), rgba(242, 146, 47, 0.06));
}

body.theme-dark:not(.auth-required) .preview-canvas-tool:hover {
  border-color: rgba(111, 174, 238, 0.58);
  color: #cce7ff;
  background: transparent;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

body.theme-dark:not(.auth-required) .preview-canvas-tool-icon {
  color: #9cc4ec;
  background: rgba(90, 166, 232, 0.14);
}

body.theme-dark:not(.auth-required) .preview-canvas-tool-text small {
  color: #a8b7c9;
}

@media (prefers-reduced-motion: reduce) {
  .preview-canvas-tools,
  .preview-canvas-tools.is-ready .preview-canvas-tool {
    animation: none !important;
  }

  .preview-canvas-tools:not(.is-ready) .preview-canvas-tool {
    opacity: 1;
    transform: none;
  }

  #previewImage {
    transition: none !important;
  }
}

.watermark-panel {
  width: min(980px, calc(100vw - 32px));
  max-height: calc(100dvh - 84px);
  overflow: auto;
}

.watermark-picker-panel {
  width: min(560px, 100%);
}

#watermarkPickerModal .watermark-picker-panel {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  max-height: min(620px, calc(100dvh - 128px));
  overflow: hidden;
}

#watermarkModal.modal-mask,
#watermarkPickerModal.modal-mask {
  place-items: start center;
  padding-top: min(7vh, 56px);
}

#watermarkPickerModal.modal-mask {
  padding-top: min(10vh, 76px);
  z-index: var(--z-modal-pick); /* 提到基础弹窗之上，确保从图片编辑台(12000)里打开时盖在其上、可点选 */
}

#watermarkModal.modal-mask {
  z-index: var(--z-modal-pick); /* 水印库从图片编辑台(12000)里打开时也要盖在其上、可点选 */
}

.watermark-library-view[hidden],
.watermark-layout[hidden] {
  display: none;
}

.watermark-library-view {
  display: grid;
  gap: 12px;
}

.watermark-library-actions {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
}

.watermark-library-actions button {
  flex: 0 0 auto;
  min-width: 92px;
}

.watermark-library {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
  justify-content: start;
  align-content: start;
  gap: 14px;
  max-height: min(650px, calc(100vh - 190px));
  overflow: auto;
  padding: 2px 4px 4px 2px;
}

.watermark-library .empty-row {
  grid-column: 1 / -1;
  display: grid;
  place-items: center;
  min-height: 132px;
  border: 1px dashed var(--border);
  border-radius: 14px;
  color: var(--muted);
  background: rgba(148, 163, 184, 0.06);
  text-align: center;
  padding: 18px;
}

.watermark-library-card {
  display: grid;
  grid-template-rows: 134px auto auto;
  gap: 9px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: #ffffff;
  padding: 10px;
  min-width: 0;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.watermark-library-card:hover {
  border-color: rgba(47, 109, 183, 0.5);
  box-shadow: 0 8px 22px rgba(16, 24, 40, 0.1);
  transform: translateY(-1px);
}

.watermark-library-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.16);
}

.watermark-library-preview {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 134px;
  min-height: 134px;
  padding: 0;
  border: 0;
  border-radius: 11px;
  background:
    linear-gradient(45deg, rgba(100, 116, 139, 0.5) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(100, 116, 139, 0.5) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(100, 116, 139, 0.5) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(100, 116, 139, 0.5) 75%),
    #eef2f6;
  background-position: 0 0, 0 9px, 9px -9px, -9px 0;
  background-size: 18px 18px;
  overflow: hidden;
  cursor: pointer;
}

.watermark-library-preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  padding: 8px;
  box-sizing: border-box;
}

.watermark-default-flag {
  position: absolute;
  top: 7px;
  left: 7px;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  box-shadow: 0 2px 6px rgba(16, 24, 40, 0.28);
  pointer-events: none;
}

.watermark-library-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.watermark-library-meta strong {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13.5px;
}

.watermark-ratio-chip {
  flex: 0 0 auto;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.1);
  color: var(--accent);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

.watermark-library-card-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

.watermark-library-card-actions .watermark-card-select {
  grid-column: 1 / -1;
}

.watermark-library-card-actions button {
  min-height: 32px;
  padding: 5px 8px;
  font-size: 12.5px;
}

.watermark-library-card-actions .watermark-card-default {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
}

.watermark-library-card-actions .watermark-card-default.active {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(47, 109, 183, 0.08);
  cursor: default;
}

.watermark-layout {
  display: grid;
  grid-template-columns: minmax(260px, 0.76fr) minmax(340px, 1.24fr);
  gap: 16px;
  align-items: start;
}

.watermark-editor-toolbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: flex-start;
  min-width: 0;
}

.watermark-list-panel,
.watermark-editor,
.watermark-maker {
  display: grid;
  gap: 10px;
  min-width: 0;
}

.watermark-editor {
  align-content: start;
}

.watermark-upload-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
}

.watermark-maker-actions {
  display: grid;
  grid-template-columns: minmax(160px, auto);
  justify-content: start;
  margin-top: 2px;
}

.watermark-template-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(112px, 1fr));
  align-items: stretch;
}

.watermark-layer-panel {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 10px;
  display: grid;
  gap: 8px;
}

.watermark-layer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.watermark-layer-head span {
  color: var(--muted);
  font-size: 12px;
}

.watermark-layer-list {
  display: grid;
  gap: 7px;
  max-height: 280px;
  overflow: auto;
}

.watermark-layer-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 6px;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #fbfcfe;
  padding: 6px;
}

.watermark-layer-row.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.12);
}

.watermark-layer-row.drag-over {
  border-color: var(--blue);
}

.watermark-layer-select {
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 8px;
  text-align: left;
  justify-content: start;
}

.watermark-layer-select img {
  width: 44px;
  height: 44px;
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #eef1f6;
}

.watermark-layer-select span {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.watermark-layer-select strong,
.watermark-layer-select small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.watermark-layer-select small {
  color: var(--muted);
  font-size: 12px;
}

.watermark-layer-eye,
.watermark-layer-delete {
  min-height: 32px;
  padding: 5px 8px;
  align-self: center;
  font-size: 12px;
}

.watermark-maker {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  background: #fbfcfe;
}

.watermark-maker-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
}

.watermark-list {
  display: grid;
  gap: 8px;
  max-height: 430px;
  overflow: auto;
  padding-right: 4px;
}

#watermarkPickerList.watermark-list {
  gap: 10px;
  max-height: none;
  min-height: 0;
  padding: 2px 4px 4px 2px;
}

.watermark-card {
  display: grid;
  grid-template-columns: 78px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  width: 100%;
  text-align: left;
  background: #ffffff;
}

#watermarkPickerList .watermark-card {
  position: relative;
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  min-height: 84px;
  box-sizing: border-box;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
}

.watermark-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.12);
}

.watermark-card img {
  width: 78px;
  height: 58px;
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #f4f7fb;
}

#watermarkPickerList .watermark-card img {
  grid-column: 1;
  grid-row: 1;
  width: 92px;
  height: 64px;
}

#watermarkPickerList .watermark-card > span:not(.ui-icon) {
  grid-column: 2;
  grid-row: 1;
}

#watermarkPickerList .watermark-card > .ui-icon {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 2;
  display: grid;
  width: 18px;
  height: 18px;
  place-items: center;
  border-radius: 6px;
  background: var(--accent);
  color: #ffffff;
  box-shadow: 0 2px 7px rgba(15, 23, 42, 0.22);
}

#watermarkPickerList .watermark-card > .ui-icon svg {
  width: 13px;
  height: 13px;
}

.watermark-card span {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.watermark-card strong,
.watermark-card small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.watermark-card small {
  color: var(--muted);
}

.watermark-stage-wrap {
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #f7f9fc;
  padding: 12px;
}

.watermark-stage {
  position: relative;
  width: min(100%, 380px);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  margin: 0 auto;
  border: 1px solid #c7d1df;
  border-radius: 8px;
  background: #f4f7fb;
  cursor: crosshair;
  touch-action: none; /* 让滚轮/双指缩放、单指拖动不被浏览器手势抢走 */
}

.watermark-stage[data-preview-bg="dark"] {
  background: #111827;
}

.watermark-stage[data-preview-bg="gray"] {
  background: #8f98a8;
}

.watermark-stage[data-preview-bg="white"] {
  background: #ffffff;
}

.watermark-stage.drag-over {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.14);
}

.watermark-stage-layer,
#watermarkStageImage {
  position: absolute;
  object-fit: contain;
  cursor: move;
  max-width: none;
  user-select: none;
  touch-action: none;
}

.watermark-stage-layer.selected {
  outline: 2px solid rgba(47, 109, 183, 0.85);
  outline-offset: 2px;
}

/* ===== 水印编辑器 v2：分区式版面，手机/电脑都适配 ===== */
.watermark-editor-v2 {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}
.wm-editor-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.wm-editor-bar > strong { font-size: 15px; font-weight: 850; }
.wm-bar-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.wm-editor-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  gap: 16px;
  align-items: start;
  min-height: 0;
}
.wm-controls {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.wm-section {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fbfcfe;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.wm-section-title { margin: 0; font-size: 13px; font-weight: 850; color: #344054; }
.wm-section-title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.wm-hint { font-size: 11.5px; color: var(--muted); }
.wm-add-image { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.wm-add-text { display: flex; flex-direction: column; gap: 8px; padding-top: 10px; border-top: 1px dashed var(--border); }
.wm-grid { display: grid; gap: 8px; }
.wm-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wm-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.wm-grid > label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: #475569;
  min-width: 0;
}
.wm-grid > label input,
.wm-grid > label select { width: 100%; min-width: 0; box-sizing: border-box; }
.wm-grid > label input[type="color"] { height: 34px; padding: 2px; }
.wm-sub { padding: 9px; border: 1px dashed var(--border); border-radius: 8px; background: #f3f7fc; }
.wm-sub[hidden] { display: none !important; }
.wm-toggle { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: #344054; cursor: pointer; }
.wm-toggle input { width: auto; flex: 0 0 auto; }
.wm-preview {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.wm-preview .watermark-stage { width: min(100%, 460px); }
.wm-stage-hint { font-size: 11.5px; color: var(--muted); line-height: 1.55; }

@media (max-width: 820px) {
  .wm-editor-body { grid-template-columns: minmax(0, 1fr); }
  .wm-preview { position: static; order: -1; }
  .wm-bar-actions { width: 100%; }
  .wm-bar-actions > .primary { flex: 1 1 auto; }
  .wm-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ===== 水印编辑器 v4：左预览直接操作 + 右侧「添加/图层/常驻检查器」列 ===== */
.watermark-editor-v3 {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}
.watermark-editor-v3 .wm-editor-body {
  grid-template-columns: minmax(0, 1.2fr) minmax(300px, 0.8fr);
}
.wm-name-field {
  flex: 1 1 220px;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: #475569;
  white-space: nowrap;
}
.wm-name-field > input { flex: 1 1 auto; min-width: 0; }
.wm-side { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.wm-add-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.wm-add-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-weight: 750;
  border-style: dashed;
}
.wm-add-btn:hover { border-color: var(--accent); color: var(--accent); }
.hidden-input { display: none !important; }
.wm-text-maker {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #f3f7fc;
}
.wm-text-maker[hidden] { display: none !important; }
.wm-text-maker-title { font-size: 13px; font-weight: 850; color: #344054; }
.wm-text-maker > input[type="text"] { width: 100%; box-sizing: border-box; }
.wm-text-maker-actions { display: flex; gap: 8px; }
.wm-text-maker-actions > .primary { flex: 1 1 auto; }
.wm-layers-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
  font-weight: 850;
  color: #344054;
  padding-top: 2px;
}
.wm-layer-list { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.wm-layer-empty {
  padding: 18px 12px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  text-align: center;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.6;
}
.wm-layer {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fff;
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.wm-layer.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.14);
}
.wm-layer.is-hidden { opacity: 0.62; }
.wm-layer.dragging { opacity: 0.4; }
.wm-layer.drag-over { border-color: var(--accent); border-style: dashed; }
.wm-layer-row { display: flex; align-items: center; gap: 8px; padding: 8px; }
.wm-layer-grip { color: #9aa6b8; cursor: grab; font-size: 14px; line-height: 1; user-select: none; flex: 0 0 auto; }
.wm-layer-pick {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
/* 全局按钮规则(更高特异度 + !important)会把按钮内容顶到中间、加左右内边距——
   用 #watermarkModal 的 ID 特异度压回(同 #poserStudioModal 的既有做法),否则缩略图悬在行中间。 */
#watermarkModal .wm-layer-pick { justify-content: flex-start !important; padding: 0 !important; }
.wm-layer-pick > img {
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  object-fit: contain;
  border-radius: 8px;
  border: 1px solid var(--border);
  background:
    repeating-conic-gradient(#e9eef5 0% 25%, #ffffff 0% 50%) 0 / 14px 14px;
}
.wm-layer-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wm-layer-meta > strong { font-size: 13px; font-weight: 750; color: #1f2a37; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wm-layer-meta > small { font-size: 11px; color: var(--muted); }
.wm-layer-icon {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.wm-layer-icon:hover { border-color: var(--accent); }
.wm-layer-icon.danger:hover { border-color: var(--danger, #dc3a3a); color: var(--danger, #dc3a3a); }
/* ── 常驻检查器：选中图层的全部参数（不再藏进图标弹出菜单） ── */
.wm-inspector {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fbfcfe;
}
.wm-inspector:empty { display: none; }
.wm-insp-empty { text-align: center; color: var(--muted); font-size: 12.5px; padding: 6px 0; }
.wm-insp-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}
.wm-insp-head > b { font-size: 13px; font-weight: 800; color: #1f2a37; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wm-insp-group { display: flex; flex-direction: column; gap: 8px; padding-top: 9px; border-top: 1px dashed var(--border); }
.wm-insp-label { font-size: 12px; font-weight: 750; color: #475569; }
.wm-insp-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.wm-slider { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #475569; white-space: nowrap; }
.wm-slider-name { flex: 0 0 52px; font-weight: 700; }
.wm-slider > input[type="range"] { flex: 1 1 auto; min-width: 0; }
.wm-slider > b { flex: 0 0 auto; min-width: 42px; text-align: right; font-variant-numeric: tabular-nums; color: #344054; font-weight: 750; }
/* 九宫格快捷位置 */
.wm-pos-grid {
  display: grid;
  grid-template-columns: repeat(3, 26px);
  grid-auto-rows: 26px;
  gap: 4px;
}
.wm-pos-grid > button {
  width: 26px;
  height: 26px;
  min-height: 26px;
  max-height: 26px;
  box-sizing: border-box;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.wm-pos-grid > button > i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #b9c4d4;
}
.wm-pos-grid > button:hover { border-color: var(--accent); }
.wm-pos-grid > button:hover > i { background: var(--accent); }
.wm-pos-grid > button.on { border-color: var(--accent); background: rgba(47, 109, 183, 0.12); }
.wm-pos-grid > button.on > i { background: var(--accent); }
/* 文字图层就地编辑 */
.wm-insp-textedit > input[type="text"] { width: 100%; box-sizing: border-box; }
.wm-insp-textrow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.wm-insp-textrow > label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: #475569; min-width: 0; }
.wm-insp-textrow > label input,
.wm-insp-textrow > label select { width: 100%; min-width: 0; box-sizing: border-box; }
.wm-insp-textrow > label input[type="color"] { height: 34px; padding: 2px; }
.wm-insp-apply { width: 100%; }

/* ── 舞台下方工具条：画布比例 / 预览背景 / 状态提示 ── */
.wm-stage-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.wm-stage-ctl { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: #475569; white-space: nowrap; }
.wm-stage-ctl > select { width: auto; min-width: 72px; }

/* 选中图层的操作框 + 缩放/旋转手柄 */
.wm-frame {
  position: absolute;
  box-sizing: border-box;
  border: 1.5px dashed rgba(47, 109, 183, 0.9);
  transform-origin: center center;
  pointer-events: none;
  z-index: 5;
}
/* 平铺态：操作框落在锚点瓦片上，用实线 + 浅底强调“拖我平移整片”。 */
.wm-frame.is-tile { border-style: solid; background: rgba(47, 109, 183, 0.08); }
.wm-frame-stem {
  position: absolute;
  left: 50%;
  top: -26px;
  width: 1.5px;
  height: 26px;
  background: rgba(47, 109, 183, 0.9);
  transform: translateX(-50%);
  pointer-events: none;
}
.wm-handle {
  position: absolute;
  width: 19px;
  height: 19px;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  background: #fff;
  color: var(--accent);
  font-size: 11px;
  line-height: 1;
  pointer-events: auto;
  touch-action: none;
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.25);
}
.wm-handle-rotate { top: -34px; left: 50%; transform: translateX(-50%); cursor: grab; }
.wm-handle-resize { right: -10px; bottom: -10px; cursor: nwse-resize; }

@media (max-width: 820px) {
  .watermark-editor-v3 .wm-editor-body { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .watermark-editor-v3 .wm-preview { position: static; order: -1; }
  /* 手机端工具栏:返回+名称一行,三个操作按钮等分一行(保存为主);不再与弹窗标题重叠 */
  .wm-editor-bar { row-gap: 8px; }
  .wm-name-field { flex: 1 1 auto; }
  .wm-bar-actions { width: 100%; display: grid; grid-template-columns: auto auto minmax(0, 1fr); }
  .wm-stage-toolbar .wm-stage-hint { flex-basis: 100%; }
  .wm-handle { width: 26px; height: 26px; font-size: 14px; }
  .wm-handle-rotate { top: -40px; }
  .wm-handle-resize { right: -13px; bottom: -13px; }
}

.monitor-body {
  display: grid;
  grid-template-columns: minmax(360px, 0.52fr) minmax(0, 0.48fr);
  gap: 18px;
  align-items: start;
  min-width: 0;
  overflow-x: hidden;
}

.task-detail-panel {
  min-width: 0;
  overflow-x: hidden;
}

.job-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
  min-height: 32px;
}

.job-meta span {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  min-height: 30px;
  padding: 6px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fbfcfe;
  color: #344054;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 任务编号(可点复制)：在 meta 行里做成可点击芯片，完整显示 job.id，点一下复制。 */
.job-meta span.job-meta-id {
  gap: 6px;
  cursor: pointer;
  white-space: normal;
}
.job-meta span.job-meta-id code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  word-break: break-all;
}
.job-meta span.job-meta-id .ui-icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  opacity: 0.6;
}
.job-meta span.job-meta-id .ui-icon svg {
  width: 100%;
  height: 100%;
}
.job-meta span.job-meta-id:hover {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  color: #255a9c;
}

/* ============================================================
   任务结果区 · 统一卡片系统（图片 / 视频 / 音频）
   响应式自适应网格 + 圆角卡片 + 图标操作；单一权威定义
   ============================================================ */
.results-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  align-items: start;
  min-width: 0;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(126px, 22vw, 168px), 1fr));
  gap: 12px;
  max-height: min(46vh, 460px);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 2px 6px 4px 2px;
  min-width: 0;
  align-content: start;
}

/* 视频/音频卡片更宽，放得下预览+标题+提示 */
.gallery:has(.media-thumb) {
  grid-template-columns: repeat(auto-fill, minmax(clamp(206px, 44vw, 282px), 1fr));
  align-content: start;
}

.gallery-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 40px 16px;
  text-align: center;
  color: var(--muted);
  border: 1px dashed var(--border);
  border-radius: 14px;
  background: var(--surface-2, #f7fafd);
}

.gallery-empty-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: rgba(47, 109, 183, 0.1);
  color: var(--accent);
}

.gallery-empty-icon .ui-icon,
.gallery-empty-icon svg {
  width: 24px;
  height: 24px;
}

.gallery-empty strong {
  color: var(--text);
  font-size: 14px;
}

.gallery-empty p {
  margin: 0;
  max-width: 280px;
  font-size: 12.5px;
  line-height: 1.5;
}

.gallery-select-bar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 11px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-2, #f6f9fc);
}

.gallery-select-bar button {
  min-height: 30px;
  padding: 5px 11px;
  font-size: 12px;
}

.gallery-select-bar span {
  color: var(--muted);
  font-size: 12px;
}

.thumb {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: #ffffff;
  min-width: 0;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
  transition:
    border-color var(--motion-premium-base) var(--motion-premium-in),
    box-shadow var(--motion-premium-base) var(--motion-premium-in);
}

.thumb:hover {
  border-color: rgba(47, 109, 183, 0.42);
  box-shadow: 0 10px 24px rgba(16, 24, 40, 0.12);
}

.thumb.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(47, 109, 183, 0.2);
}

.thumb.partial {
  border-color: #e0c074;
}

/* 选择勾选：左上角正方形复选 */
.thumb-select {
  position: absolute;
  z-index: 4;
  top: 8px;
  left: 8px;
  display: block;
  width: 22px;
  min-width: 22px;
  max-width: 22px;
  height: 22px;
  min-height: 22px;
  max-height: 22px;
  cursor: pointer;
}

.thumb-select input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.thumb-select span {
  display: block;
  width: 22px;
  min-width: 22px;
  max-width: 22px;
  height: 22px;
  min-height: 22px;
  max-height: 22px;
  border: 1.5px solid #cdd7e3;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 1px 5px rgba(16, 24, 40, 0.18);
  transition: background 0.14s ease, border-color 0.14s ease;
}

.thumb-select input:checked + span {
  border-color: var(--accent);
  background: var(--accent);
}

.thumb-select input:checked + span::after {
  content: "";
  position: absolute;
  left: 8px;
  top: 5px;
  width: 5px;
  height: 9px;
  border: solid #ffffff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.thumb img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  background: #eef1f6;
}

.thumb-preview {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: #eef1f6;
  cursor: zoom-in;
  overflow: hidden;
  min-height: 0;
}

.thumb-preview:hover {
  border-color: transparent;
}

/* 视频/音频：竖向卡片（与图片卡片同一网格），覆盖旧的 2 列 grid-areas 布局 */
.media-thumb {
  display: flex;
  flex-direction: column;
  grid-template-columns: none;
  grid-template-rows: none;
  grid-template-areas: none;
  gap: 0;
  padding: 0;
  border-radius: 12px;
}

.media-thumb .thumb-select {
  top: 8px;
  left: 8px;
}

.media-thumb .thumb-preview {
  position: relative;
  display: grid;
  place-items: center;
  gap: 6px;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 0;
  max-height: none;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  color: #2f5e88;
  background:
    linear-gradient(135deg, rgba(47, 109, 183, 0.14), rgba(47, 96, 156, 0.1)),
    #f1f5fb;
  overflow: hidden;
}

.media-thumb-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: #0f172a;
  pointer-events: none;
}

.media-play-badge {
  position: absolute;
  left: 8px;
  bottom: 8px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.74);
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
}

.media-thumb-icon {
  width: 44px;
  height: 44px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: #ffffff;
  font-size: 15px;
  font-weight: 800;
}
/* 内容改用矢量图标(旧「音/文」文字块已下线):图标随圆底尺寸适配 */
.media-thumb-icon svg { width: 21px; height: 21px; }

.media-thumb .thumb-preview strong {
  font-size: 13px;
}

.media-thumb .media-thumb-footer {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 8px 9px 4px;
}

.media-thumb .media-thumb-footer > span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #1f2937;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.3;
}

.media-thumb-prompt {
  margin: 0;
  padding: 0 9px 9px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.task-detail-panel .item-row {
  grid-template-columns: minmax(64px, auto) minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  padding: 10px 2px;
}

.task-detail-panel .item-row b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: max-content;
  min-height: 24px;
  padding: 4px 9px;
  border: 1px solid #d4e2ef;
  border-radius: 999px;
  background: #f2f7fb;
  color: #2f6db7;
  font-size: 12px;
  line-height: 1;
}

.task-detail-panel .item-row > div {
  min-width: 0;
}

.task-detail-panel .item-row strong {
  display: block;
  overflow: hidden;
  color: #1f2937;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.task-detail-panel .item-row p {
  display: -webkit-box;
  margin-top: 4px;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.thumb-badge {
  position: absolute;
  z-index: 3;
  right: 8px;
  top: 8px;
  padding: 3px 7px;
  border-radius: 7px;
  background: rgba(15, 23, 42, 0.78);
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
}

.thumb-footer {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 9px;
  min-width: 0;
}

.thumb-footer > span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #475569;
  font-size: 12px;
}

/* 卡片底部操作 = 紧凑图标按钮 */
.thumb-footer .icon-action {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  min-width: 30px;
  min-height: 30px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  color: #5b6678;
  white-space: nowrap;
}

.thumb-footer .icon-action .ui-icon {
  display: grid;
  width: 16px;
  height: 16px;
}

.thumb-footer .icon-action .ui-icon svg {
  width: 16px;
  height: 16px;
}

.thumb-footer .icon-action:hover {
  background: #f1f5f9;
}

.thumb-footer .thumb-watermark {
  color: var(--accent);
  border-color: #cfe0f2;
  background: #f2f7fb;
}

.thumb-footer .thumb-watermark:hover {
  background: #e6f0fb;
}

.thumb-footer .thumb-delete {
  color: #c2410c;
}

.thumb-footer .thumb-delete:hover {
  background: #fef2f0;
  border-color: #f4c7bb;
}

.item-table {
  max-height: clamp(180px, calc(100vh - 620px), 320px);
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  border-top: 0;
  min-width: 0;
}
/* 没有需要关注的项(全部成功)时,结果明细区直接收起,不在图片后面留一个空框 */
.item-table:empty {
  display: none;
}

.item-row {
  display: grid;
  grid-template-columns: 94px 1fr;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid #edf0f5;
}

.item-row b {
  color: #344054;
}

.item-row p {
  color: var(--muted);
  margin-top: 3px;
  overflow-wrap: anywhere;
}

.error-category {
  display: inline-flex;
  margin-left: 6px;
  padding: 2px 6px;
  border-radius: 999px;
  background: #fff1f0;
  color: var(--danger);
  border: 1px solid #ffc9c4;
  font-size: 12px;
  font-weight: 700;
}

.toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  max-width: min(520px, calc(100vw - 36px));
  max-height: min(30vh, 240px);
  overflow: auto;
  overflow-wrap: anywhere;
  background: #101828;
  color: #ffffff;
  padding: 13px 15px;
  border-radius: 8px;
  box-shadow: var(--shadow);
  z-index: var(--z-toast);
}

.shortcut-panel {
  max-width: min(720px, calc(100vw - 28px));
}

.shortcut-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.shortcut-grid div {
  display: grid;
  grid-template-columns: minmax(140px, auto) 1fr;
  gap: 8px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #fbfcfe;
}

.shortcut-keys {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
  color: var(--muted);
  white-space: nowrap;
}

kbd {
  display: inline-flex;
  min-width: 26px;
  height: 24px;
  padding: 0 7px;
  align-items: center;
  justify-content: center;
  border: 1px solid #c7d0dd;
  border-bottom-width: 2px;
  border-radius: 6px;
  background: #ffffff;
  color: #344054;
  font-size: 12px;
  font-weight: 760;
  white-space: nowrap;
}

.context-menu {
  position: fixed;
  z-index: 80;
  min-width: 236px;
  max-height: calc(100vh - 16px);
  overflow: auto;
  padding: 8px;
  border: 1px solid #d9e2ee;
  border-radius: 10px;
  background: #fbfcfe;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.14);
}

.context-menu button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  padding: 8px 9px;
  text-align: left;
  cursor: pointer;
  font-size: 13px;
  line-height: 1.25;
}

.context-menu .context-label {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  gap: 8px;
}

.context-menu .context-copy {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.context-menu .context-title-line {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  gap: 6px;
  font-weight: 760;
}

.context-menu .context-description {
  color: #667085;
  font-size: 12px;
  font-weight: 560;
  line-height: 1.25;
}

.context-menu .context-description .context-price {
  vertical-align: middle;
}

.context-menu .context-tag {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 6px;
  border: 1px solid rgba(148, 163, 184, 0.45);
  border-radius: 999px;
  background: rgba(248, 250, 252, 0.86);
  color: #475467;
  font-size: 11px;
  font-weight: 760;
}

.context-menu-heading {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 2px 5px;
  padding: 6px 6px 5px;
  border-bottom: 1px solid #edf1f6;
  color: #344054;
  font-size: 12px;
  font-weight: 850;
}

.context-menu-heading:first-child {
  margin-top: 0;
}

.context-menu-divider {
  height: 1px;
  margin: 8px 2px;
  background: #edf1f6;
}

.context-menu .context-color-badge,
.command-palette-list .context-color-badge {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  border-radius: 8px;
  /* 柔和浅色调(同无限画布 .context-icon)：浅色 accent 背景 + 同色图标，不再实心五颜六色 */
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 13%, #ffffff);
  color: var(--menu-accent, #2f6db7);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
}

.context-menu .context-icon {
  display: inline-grid;
  place-items: center;
  width: 23px;
  height: 23px;
  flex: 0 0 23px;
  border-radius: 7px;
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 13%, #ffffff);
  color: var(--menu-accent, #2f6db7);
}

.context-menu .context-icon svg,
.context-menu .context-color-badge svg,
.command-palette-list .context-color-badge svg {
  width: 12.5px;
  height: 12.5px;
  stroke-width: 1.5;
}

.context-menu button.module-create {
  border-color: transparent;
  background: transparent;
  color: #1d2939;
  box-shadow: none;
}

.context-menu button.module-create:hover {
  border-color: color-mix(in srgb, var(--menu-accent, #2f6db7) 24%, #e5edf6);
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 8%, #ffffff);
}

.context-menu button:hover {
  background: #eef3f8;
}

.context-menu button.danger {
  color: var(--danger);
}

.context-menu button:disabled {
  color: #98a2b3;
  cursor: not-allowed;
  opacity: 0.72;
}

.context-menu .shortcut-hint {
  color: var(--muted);
  font-size: 12px;
}

.workflow-stage-wrap.panning {
  cursor: grabbing;
}

.litegraph.litecontextmenu,
.litegraph.litecontextmenu.dark {
  min-width: 238px;
  padding: 8px;
  border: 1px solid #d9e2ee;
  border-radius: 10px;
  background: #fbfcfe !important;
  background-color: #fbfcfe !important;
  color: #243042 !important;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.14) !important;
  font-family: "Microsoft YaHei", "Segoe UI", Arial, sans-serif;
  z-index: var(--z-overlay);
}

/* @ 引用参考图浮层(openPromptMentionPop):提示词框输入 @ 弹出,点选插入「图片N」。 */
.prompt-mention-pop {
  position: fixed;
  z-index: 100000;
  box-sizing: border-box;
  padding: 10px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #d9e2ee);
  border-radius: 12px;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.16);
}
.prompt-mention-title { margin-bottom: 8px; color: #5c728a; font-size: 12px; font-weight: 650; }
.prompt-mention-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px; max-height: 42vh; overflow: auto; }
.prompt-mention-item {
  position: relative; padding: 0; border: 1px solid var(--border, #d9e2ee); border-radius: 10px;
  overflow: hidden; background: #f4f7fb; cursor: pointer; aspect-ratio: 1;
}
.prompt-mention-item:hover { border-color: #2f6db7; box-shadow: 0 0 0 2px rgba(47, 109, 183, 0.16); }
.prompt-mention-item.is-active {
  border-color: #2f6db7;
  box-shadow: 0 0 0 2.5px rgba(47, 109, 183, 0.55), 0 4px 12px rgba(47, 109, 183, 0.22);
  transform: translateY(-1px);
}
.prompt-mention-item.is-active .prompt-mention-badge { background: #2f6db7; }
.prompt-mention-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 视频/音频参考:矢量图标占位(替代旧「视/音」文字块) */
.prompt-mention-ico {
  display: grid; place-items: center; width: 100%; height: 100%;
  background: linear-gradient(160deg, #eef5ff, #e3ecfa); color: #2f6db7;
}
.prompt-mention-ico[data-kind="audio"] { background: linear-gradient(160deg, #f2edff, #e8e2fb); color: #6d5bd0; }
.prompt-mention-ico svg { width: 26px; height: 26px; }
body.theme-dark .prompt-mention-ico { background: linear-gradient(160deg, #1b2740, #202c46); color: #8fb4e6; }
body.theme-dark .prompt-mention-ico[data-kind="audio"] { background: linear-gradient(160deg, #241f3a, #2b2547); color: #a99bea; }
.prompt-mention-item.dead { display: none; }
.prompt-mention-badge {
  position: absolute; left: 4px; bottom: 4px; padding: 1px 6px; border-radius: 6px;
  background: rgba(17, 24, 39, 0.68); color: #fff; font-size: 11px; font-weight: 650; pointer-events: none;
}
.prompt-mention-empty { padding: 6px 4px; color: #5c728a; font-size: 12.5px; }
body.theme-dark .prompt-mention-pop { background: #252a34; border-color: #454c5c; box-shadow: 0 14px 34px rgba(0, 0, 0, 0.42); }
body.theme-dark .prompt-mention-item { background: #1b1f28; border-color: #454c5c; }
body.theme-dark .prompt-mention-title, body.theme-dark .prompt-mention-empty { color: #9aa8bd; }

/* 桌面全站自绘下拉面板(openDesktopSelectPanel):替代原生 select 下拉。
   默认单列;比例类(.hui-ratio-pair)竖横配对两列=左竖右横一一对齐,auto/1:1 等无方向项占整行;
   面板宽度由 JS 设为与触发框两边对齐。 */
.hui-select-panel {
  position: fixed;
  z-index: 100000; /* 弹窗(modal)里的 select 也要能弹出面板,必须盖过全部弹层 */
  display: grid;
  grid-template-columns: 1fr;
  gap: 3px;
  box-sizing: border-box;
  padding: 6px;
  max-height: min(58vh, 480px);
  overflow: auto;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #d9e2ee);
  border-radius: 10px;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.16);
}
.hui-select-panel.hui-ratio-pair { grid-template-columns: 1fr 1fr; gap: 4px; }
.hui-select-opt {
  min-height: 32px;
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: #263244;
  font-size: 13px;
  font-weight: 570;
  line-height: 1.25;
  text-align: left;
  cursor: pointer;
}
.model-logo {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 7px;
  background: #fff;
  color: #111827;
  border: 1px solid rgba(15, 23, 42, 0.10);
  box-shadow: 0 2px 5px rgba(15, 23, 42, 0.10);
  font-size: 9.5px;
  font-weight: 850;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  overflow: hidden;
}
.model-logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.model-logo.has-image { font-size: 0; }
.model-logo.has-image {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
.model-logo:not(.has-image) {
  background: linear-gradient(135deg, #64748b, #94a3b8);
  color: #fff;
  border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22), 0 2px 5px rgba(15, 23, 42, 0.12);
}
.model-logo:not(.has-image).model-logo-sora { background: linear-gradient(135deg, #111827, #2563eb); }
.model-logo:not(.has-image).model-logo-openai { background: linear-gradient(135deg, #101828, #475467); }
.model-logo:not(.has-image).model-logo-gemini { background: linear-gradient(135deg, #2563eb, #16a34a 58%, #f59e0b); }
.model-logo:not(.has-image).model-logo-nanobanana { background: linear-gradient(135deg, #7c3aed, #f59e0b); }
.model-logo:not(.has-image).model-logo-doubao { background: linear-gradient(135deg, #0f172a, #0ea5e9 48%, #ec4899); }
.model-logo:not(.has-image).model-logo-volcengine { background: linear-gradient(135deg, #2563eb, #ef4444); }
.model-logo:not(.has-image).model-logo-kling { background: linear-gradient(135deg, #1d4ed8, #7c3aed); }
.model-logo:not(.has-image).model-logo-grok,
.model-logo:not(.has-image).model-logo-xai { background: linear-gradient(135deg, #020617, #475569); }
.model-logo:not(.has-image).model-logo-flux { background: linear-gradient(135deg, #111827, #f97316); }
.model-logo:not(.has-image).model-logo-qwen { background: linear-gradient(135deg, #2563eb, #7c3aed); }
.model-logo:not(.has-image).model-logo-minimax { background: linear-gradient(135deg, #0f766e, #14b8a6); }
.model-logo:not(.has-image).model-logo-suno { background: linear-gradient(135deg, #7c2d12, #f59e0b); }
.model-logo:not(.has-image).model-logo-deepseek { background: linear-gradient(135deg, #1d4ed8, #06b6d4); }
.model-logo:not(.has-image).model-logo-anthropic,
.model-logo:not(.has-image).model-logo-claude { background: linear-gradient(135deg, #7c3f2d, #d97706); }
.model-logo:not(.has-image).model-logo-luma { background: linear-gradient(135deg, #111827, #8b5cf6); }
.hui-model-select-panel { gap: 4px; }
.hui-select-opt.hui-select-model-opt {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 6px 9px;
}
.hui-select-model-main {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  width: min(100%, 232px);
  min-width: 0;
}
.hui-select-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
select.model-select-has-logo {
  padding-left: 38px !important;
  background-color: #fff;
}
select.model-select-has-logo[data-model-brand-key="openai"],
select.model-select-has-logo[data-model-brand-key="grok"],
select.model-select-has-logo[data-model-brand-key="xai"],
select.model-select-has-logo[data-model-brand-key="suno"],
select.model-select-has-logo[data-model-brand-key="flux"],
select.model-select-has-logo[data-model-brand-key="anthropic"] {
  filter: none;
}
.hui-ratio-pair .hui-select-opt { text-align: center; border-color: var(--border, #d9e2ee); }
.hui-select-opt:hover:not(:disabled) { border-color: #d8e2ee; background: #eef3f8; color: #111827; }
.hui-select-opt.active { border-color: #2f6db7; background: rgba(47, 109, 183, 0.08); color: #2f6db7; font-weight: 650; }
.hui-select-opt:disabled { opacity: 0.45; cursor: default; }
.hui-select-opt.ratio-span { grid-column: 1 / -1; }
body.theme-dark .hui-select-panel { background: #252a34; border-color: #454c5c; box-shadow: 0 14px 34px rgba(0, 0, 0, 0.42); }
body.theme-dark .hui-select-opt { color: #dbe2ee; }
body.theme-dark .hui-ratio-pair .hui-select-opt { border-color: #454c5c; }
body.theme-dark .hui-select-opt:hover:not(:disabled) { border-color: #4a5364; background: #2d3442; color: #f1f5fb; }
body.theme-dark .hui-select-opt.active { border-color: #6f9dd8; background: rgba(111, 157, 216, 0.14); color: #9ec2ee; }
body.theme-dark .model-logo { border-color: rgba(255, 255, 255, 0.16); box-shadow: 0 2px 7px rgba(0, 0, 0, 0.3); }
body.theme-dark .model-logo.has-image { border-color: transparent; box-shadow: none; }
body.theme-dark .model-logo.has-image:is(.model-logo-openai, .model-logo-grok, .model-logo-xai, .model-logo-suno, .model-logo-flux, .model-logo-anthropic) img {
  filter: invert(1);
}
body.theme-dark .model-logo:not(.has-image) { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18), 0 2px 7px rgba(0, 0, 0, 0.3); }

/* 比例菜单竖横配对两列:JS(workflowRatioMenuOrder)已把选项重排成
   [无方向项(整行)…, 竖,横, 竖,横 …],这里两列 grid=每行左竖右横一一对齐,列表高度直接减半。 */
.litegraph.litecontextmenu.hui-ratio-pair-menu {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px 6px;
  min-width: 196px;
}
.litegraph.litecontextmenu.hui-ratio-pair-menu .litemenu-entry { text-align: center; margin: 0; min-height: 30px; padding: 6px 8px; }
.litegraph.litecontextmenu.hui-ratio-pair-menu .litemenu-entry.ratio-span { grid-column: 1 / -1; }
.litegraph.litecontextmenu.hui-ratio-pair-menu .ai-lite-menu-drag-handle { grid-column: 1 / -1; }

.litegraph.litecontextmenu.hui-model-lite-menu {
  min-width: min(260px, calc(100vw - 24px));
  max-width: min(320px, calc(100vw - 24px));
  padding: 7px;
}
.litegraph.litecontextmenu.hui-model-lite-menu .litemenu-entry.hui-model-lite-entry {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 6px 9px;
  border-radius: 9px;
  text-align: left;
}
.litegraph.litecontextmenu.hui-model-lite-menu .litemenu-entry.hui-model-lite-entry .hui-select-model-main {
  width: min(100%, 232px);
}

.litegraph.litecontextmenu .ai-lite-menu-drag-handle {
  height: 16px;
  margin: -3px -2px 5px;
  color: #8a98aa;
  cursor: move;
  font-size: 10px;
  font-weight: 750;
  line-height: 16px;
  text-align: center;
  user-select: none;
}

.litegraph.litecontextmenu .litemenu-title {
  margin: -2px -2px 7px;
  padding: 0 2px 7px;
  border-bottom: 1px solid #edf1f6;
  background: transparent;
  color: #1d2430;
  font-size: 13px;
  font-weight: 800;
}

.litegraph.litecontextmenu .litemenu-entry,
.litegraph.litecontextmenu .litemenu-entry.submenu,
.litegraph.litecontextmenu.dark .litemenu-entry,
.litegraph.litecontextmenu.dark .litemenu-entry.submenu {
  min-height: 32px;
  margin: 3px 0;
  padding: 8px 10px;
  border: 1px solid transparent !important;
  border-radius: 8px;
  background: transparent !important;
  background-color: transparent !important;
  color: #263244 !important;
  font-size: 13px;
  font-weight: 640;
  line-height: 1.25;
}

.litegraph.litecontextmenu .litemenu-entry:hover:not(.disabled):not(.separator),
.litegraph.litecontextmenu.dark .litemenu-entry:hover:not(.disabled):not(.separator) {
  border-color: #d8e2ee !important;
  background: #eef3f8 !important;
  background-color: #eef3f8 !important;
  color: #111827 !important;
}

.litegraph.litecontextmenu .litemenu-entry.has_submenu {
  border-right: 0;
}

.litegraph.litecontextmenu .litemenu-entry.has_submenu::after {
  content: ">";
  float: right;
  color: #667085;
}

.litegraph.litecontextmenu .litemenu-entry.separator {
  border-top: 1px solid #edf0f5;
  border-bottom: 0;
  height: 1px;
  margin: 7px 0;
  background: transparent !important;
}

.litegraph.litesearchbox,
.graphdialog,
.graphdialog.rounded {
  font-family: "Microsoft YaHei", "Segoe UI", Arial, sans-serif;
}

.graphdialog,
.graphdialog.rounded {
  display: grid !important;
  grid-template-columns: minmax(240px, 1fr) auto;
  align-items: start;
  gap: 8px 10px;
  width: fit-content;
  min-width: 360px;
  min-height: 66px;
  max-width: none;
  max-height: min(640px, calc(100vh - 32px));
  padding: 12px !important;
  border: 1px solid #cbd5e1;
  border-radius: 10px !important;
  background: #ffffff !important;
  background-color: #ffffff !important;
  color: #1d2430 !important;
  box-shadow: 0 8px 18px rgba(20, 31, 48, 0.08) !important;
  resize: none;
  overflow: visible;
  z-index: calc(var(--z-overlay) + 1);
}

.graphdialog .name {
  grid-column: 1 / -1;
  min-height: 28px !important;
  padding: 0 0 6px 2px !important;
  border-bottom: 1px solid #edf0f5;
  color: #1d2430 !important;
  cursor: move;
  font-size: 13px;
  font-weight: 750;
  user-select: none;
}

.graphdialog input.value,
.graphdialog textarea.value,
.graphdialog input,
.graphdialog textarea,
.graphdialog select {
  width: 100%;
  min-width: 180px;
  min-height: 34px;
  margin: 0 !important;
  padding: 7px 10px !important;
  border: 1px solid #b8c7d9 !important;
  border-radius: 7px !important;
  background: #f8fafc !important;
  background-color: #f8fafc !important;
  color: #111827 !important;
  outline: none !important;
}

.graphdialog input.value:focus,
.graphdialog textarea.value:focus,
.graphdialog input:focus,
.graphdialog textarea:focus,
.graphdialog select:focus {
  border-color: #16855f !important;
  box-shadow: 0 0 0 3px rgba(22, 133, 95, 0.13);
}

.graphdialog textarea.value,
.graphdialog textarea {
  grid-column: 1 / -1;
  align-self: start;
  justify-self: start;
  width: min(520px, calc(100vw - 72px));
  min-height: 220px;
  min-width: 300px;
  max-width: none;
  max-height: calc(100vh - 140px);
  resize: both;
  vertical-align: top;
}

.graphdialog button,
.graphdialog button.rounded {
  justify-self: end;
  align-self: center;
  min-height: 34px;
  margin: 0 !important;
  padding: 0 14px;
  border: 1px solid #16855f !important;
  border-radius: 7px !important;
  background: #16855f !important;
  color: #ffffff !important;
  font-weight: 700;
  cursor: pointer;
}

.graphdialog button:hover {
  background: #126b4e !important;
}

.litegraph.litesearchbox.graphdialog.rounded {
  display: block !important;
  width: 280px;
  min-width: 260px;
  padding: 8px;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  background: #ffffff !important;
  color: #243042;
  box-shadow: none !important;
  resize: none;
  overflow: visible;
  z-index: calc(var(--z-overlay) + 1);
}

.litegraph.litesearchbox .name {
  display: block;
  margin: -8px -8px 8px;
  padding: 8px 10px;
  border-bottom: 1px solid #edf0f5;
  background: #f7f9fc;
  color: #1d2430 !important;
  cursor: move;
  user-select: none;
  font-size: 13px;
  font-weight: 750;
}

.litegraph.litesearchbox input.value {
  width: 100%;
  height: 32px;
  margin-bottom: 8px;
  padding: 0 10px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  background: #ffffff;
  color: #1d2430;
  outline: none;
}

.litegraph.litesearchbox .helper {
  max-height: 280px;
  overflow: auto;
}

.litegraph.litesearchbox.graphdialog.rounded .helper .litegraph.lite-search-item,
.litegraph.litesearchbox .lite-search-item {
  min-height: 30px;
  padding: 7px 10px;
  background: #e8f6ef !important;
  background-color: #e8f6ef !important;
  background-image: none !important;
  border: 1px solid #b9dfcf !important;
  border-radius: 6px;
  color: var(--accent-strong) !important;
  font-size: 13px;
  font-weight: 650;
  line-height: 1.25;
  box-shadow: none !important;
}

.litegraph.litesearchbox.graphdialog.rounded .helper .litegraph.lite-search-item:hover,
.litegraph.litesearchbox.graphdialog.rounded .helper .litegraph.lite-search-item.selected,
.litegraph.litesearchbox .lite-search-item:hover,
.litegraph.litesearchbox .lite-search-item.selected {
  background: #16855f !important;
  background-color: #16855f !important;
  background-image: none !important;
  color: #ffffff !important;
}

.litegraph.litecontextmenu .ai-lite-menu-node {
  display: grid !important;
  grid-template-columns: 26px minmax(0, 1fr) 12px;
  align-items: center !important;
  gap: 9px !important;
  min-height: 34px !important;
  margin: 1px 0 !important;
  padding: 6px 8px !important;
  border: 1px solid transparent !important;
  border-radius: 7px !important;
  color: #1d2939 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.litegraph.litecontextmenu .ai-lite-menu-node[data-workflow-lite-drag-type] {
  cursor: grab;
}

.litegraph.litecontextmenu .ai-lite-menu-node.workflow-menu-drag-source {
  opacity: 0.55;
  cursor: grabbing;
}

.litegraph.litecontextmenu .ai-lite-menu-node:hover {
  border-color: color-mix(in srgb, var(--menu-accent, #2f6db7) 24%, #e5edf6) !important;
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 8%, #ffffff) !important;
}

.litegraph.litecontextmenu .ai-lite-menu-node.has_submenu::after {
  float: none;
  justify-self: end;
  align-self: center;
}

.litegraph.litecontextmenu .ai-lite-menu-node > span:not(.ai-lite-menu-badge) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.litegraph.litecontextmenu .ai-lite-menu-badge {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: 0 0 26px;
  border-radius: 8px;
  /* 柔和浅色调(同无限画布 .context-icon)：浅色 accent 背景 + 同色图标，不再实心五颜六色 */
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 13%, #ffffff);
  color: var(--menu-accent, #2f6db7);
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
}

.litegraph.litecontextmenu .ai-lite-menu-badge svg,
.workflow-menu-drag-badge svg,
.workflow-module-icon svg,
.infinite-card-badge svg {
  width: 12.5px;
  height: 12.5px;
  stroke-width: 1.5;
}

@media (max-width: 820px) {
  .topbar {
    position: static;
    width: auto;
    height: auto;
    min-height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    box-shadow: none;
    display: grid;
    grid-template-columns: 1fr;
    align-items: stretch;
    gap: 12px;
  }

  .topbar .top-actions {
    margin-top: 0;
  }

  .module-nav {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .layout {
    margin-left: 0;
    grid-template-columns: 1fr;
    min-height: calc(100vh - 180px);
  }

  .layout.media-tool-layout {
    grid-template-columns: 1fr;
  }

  body.sidebar-collapsed .topbar {
    width: auto;
    padding: 14px;
  }

  body.sidebar-collapsed .brand-row {
    grid-template-columns: minmax(0, 1fr) auto;
    justify-items: stretch;
  }

  body.sidebar-collapsed .brand-full {
    display: inline;
  }

  body.sidebar-collapsed .brand-text p,
  body.sidebar-collapsed .module-tab strong,
  body.sidebar-collapsed .module-tab span {
    display: block;
  }

  body.sidebar-collapsed .module-tab {
    grid-template-rows: 20px 18px;
    justify-items: start;
    align-items: center;
    align-content: center;
    min-height: 68px;
    padding: 13px 14px;
    text-align: left;
  }

  body.sidebar-collapsed .brand-short,
  body.sidebar-collapsed .module-tab::before,
  body.sidebar-collapsed .topbar .state-pill::before,
  body.sidebar-collapsed .topbar .icon-button::before {
    display: none;
    content: "";
  }

  body.sidebar-collapsed .topbar .state-pill,
  body.sidebar-collapsed .topbar .icon-button {
    font-size: 14px;
  }

  .watermark-layout {
    grid-template-columns: 1fr;
  }

  .tool-grid,
  .model-category-panel,
  .settings-panel > .form-grid,
  .model-category-fields {
    grid-template-columns: 1fr;
  }

  .text-chat-shell {
    grid-template-columns: 240px minmax(0, 1fr);
  }

  .text-chat-topbar {
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  .text-chat-modelbar {
    justify-content: flex-start;
  }

  .text-chat-modelbar > label:not(.switch-row) {
    width: min(340px, 100%);
  }

  .watermark-layer-list {
    max-height: 190px;
  }
}

@media (max-width: 720px) {
  .topbar {
    height: auto;
    align-items: flex-start;
    gap: 12px;
    padding: 14px;
  }

  .module-nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .layout {
    padding: 10px;
  }

  .form-grid,
  .options-grid,
  .stats-grid,
  .key-add-row,
  .tool-grid,
  .model-category-panel,
  .settings-panel > .form-grid,
  .model-category-fields {
    grid-template-columns: 1fr;
  }

  .key-row {
    grid-template-columns: 28px 1fr;
  }

  .key-row button {
    grid-column: 2;
  }

  .category-key-add-row,
  .category-key-row {
    grid-template-columns: 1fr;
  }

  .monitor-header {
    display: grid;
  }

  .job-row,
  .case-row {
    grid-template-columns: 1fr;
  }

  .job-reuse,
  .job-favorite {
    grid-column: auto;
    grid-row: auto;
  }

  .monitor-body {
    grid-template-columns: 1fr;
  }

  .job-list {
    max-height: 260px;
  }

  .results-split {
    grid-template-columns: 1fr;
  }

  .gallery,
  .item-table {
    max-height: 320px;
  }

  .preview-tools,
  .watermark-controls,
  .watermark-maker-grid,
  .watermark-upload-row,
  .watermark-template-actions,
  .shortcut-grid {
    grid-template-columns: 1fr;
  }

  .watermark-editor-toolbar {
    display: grid;
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  .watermark-stage-wrap {
    padding: 8px;
  }

  .watermark-library {
    grid-template-columns: 1fr;
  }
}

.workflow-panel,
.infinite-canvas-panel {
  padding: 0;
}

.layout.workflow-layout .workbench,
.layout.canvas-layout .workbench {
  overflow: hidden;
}

.layout.workflow-layout .tabs,
.layout.canvas-layout .tabs {
  display: none;
}

.layout.workflow-layout .module-workflow-panel {
  display: block;
}

.layout.canvas-layout .infinite-canvas-panel {
  display: block;
}

.infinite-canvas-shell {
  --canvas-bg: #f6f9fb;
  --canvas-panel: rgba(255, 255, 255, 0.9);
  --canvas-panel-strong: #ffffff;
  --canvas-border: rgba(203, 213, 225, 0.82);
  --canvas-ink: #0f172a;
  --canvas-muted: #64748b;
  --canvas-brand: #2f6db7;
  --canvas-brand-soft: #eaf2fb;
  --canvas-blue: #2563eb;
  display: block;
  gap: 0;
  /* 填满外层(workbench→面板)的高度链，不再用 calc(100vh - 魔法数) */
  height: 100%;
  min-height: 0;
  background: transparent;
  color: var(--canvas-ink);
  /* 内层不再当卡片(外观交给最外面的 workbench 卡片)，只透明填充 */
  border: 0;
  border-radius: 0;
  overflow: hidden;
}

.infinite-canvas-sidebar,
.infinite-canvas-inspector {
  min-height: 0;
  padding: 14px;
  background: #fbfcfe;
  overflow: auto;
}

.infinite-canvas-sidebar {
  display: none;
}

.infinite-canvas-inspector {
  display: none;
  border-left: 1px solid var(--border);
}

.infinite-canvas-head h2 {
  font-size: 20px;
  line-height: 1.2;
}

.infinite-canvas-head p,
.infinite-canvas-tip span {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  line-height: 1.55;
}

.infinite-canvas-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: 14px;
}

.infinite-canvas-board-label {
  display: grid;
  gap: 7px;
  margin-top: 14px;
  color: var(--muted);
  font-weight: 700;
}

.infinite-canvas-board-label select {
  min-height: 38px;
  border-radius: 8px;
  border: 1px solid #cad6e5;
  background: #ffffff;
  color: var(--text);
  padding: 0 10px;
  font-weight: 750;
}

.infinite-canvas-tip {
  margin-top: 12px;
  padding: 12px;
  border: 1px dashed #b8c8dc;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.76);
}

.infinite-canvas-main {
  min-width: 0;
  min-height: 0;
  display: block;
  position: relative;
  height: 100%;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.infinite-canvas-toolbar {
  position: absolute;
  inset: 0;
  z-index: 20;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  pointer-events: none;
}

.canvas-board-row {
  position: absolute;
  top: 16px;
  left: 86px;
  right: auto;
  width: clamp(320px, calc(100% - 540px), 390px);
  z-index: 22;
  display: grid;
  grid-template-columns: 112px minmax(120px, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--canvas-border);
  border-radius: 18px;
  background: var(--canvas-panel);
  box-shadow: none;
  backdrop-filter: blur(18px);
  pointer-events: auto;
}

.canvas-board-row > label {
  display: grid;
  gap: 4px;
  color: var(--canvas-muted);
  font-size: 11px;
  font-weight: 850;
}

.canvas-board-row > label input,
.canvas-board-row > label select {
  min-height: 30px;
  border: 1px solid rgba(203, 213, 225, 0.9);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.9);
  color: var(--canvas-ink);
  font-size: 13px;
}

.canvas-board-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
  flex-wrap: nowrap;
  min-width: 0;
}

.canvas-board-actions button {
  min-height: 30px;
  padding: 0 8px;
  border-color: #cfe0f4;
  background: #f8fbff;
  color: #2563a7;
  font-size: 12px;
  white-space: nowrap;
}

.canvas-board-actions .canvas-legacy-add {
  display: none;
}

.canvas-board-actions #canvasNewBoardBtn,
.canvas-board-actions #canvasDuplicateBoardBtn,
.canvas-board-actions #canvasMediaLibraryBtn,
.canvas-board-actions #canvasUndoBtn,
.canvas-board-actions #canvasRedoBtn {
  display: none;
}

.canvas-board-actions .workflow-dirty-badge {
  min-height: 28px;
  padding: 0 8px;
  white-space: nowrap;
}

.canvas-side-dock {
  position: absolute;
  top: 86px;
  left: 18px;
  z-index: 24;
  display: grid;
  gap: 10px;
  padding: 10px;
  border: 1px solid var(--canvas-border);
  border-radius: 22px;
  background: var(--canvas-panel);
  box-shadow: none;
  backdrop-filter: blur(16px);
  pointer-events: auto;
}

.canvas-dock-button {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid #d6e1eb;
  border-radius: 16px;
  background: #ffffff;
  color: #334155;
  font-size: 15px;
  font-weight: 950;
  cursor: pointer;
  transition: transform 150ms ease, border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
}

.canvas-dock-button:hover {
  transform: translateY(-1px);
  border-color: rgba(47, 109, 183, 0.42);
  background: #eaf2fb;
  box-shadow: 0 10px 24px rgba(47, 109, 183, 0.12);
}

.canvas-dock-button.primary-action {
  border-color: rgba(47, 109, 183, 0.42);
  background: linear-gradient(135deg, #2f6db7 0%, #2563eb 100%);
  color: #ffffff;
  font-size: 24px;
  line-height: 1;
}

.canvas-ai-composer {
  display: grid;
  position: absolute;
  top: 16px;
  right: 16px;
  bottom: 16px;
  left: auto;
  transform: none;
  z-index: 23;
  width: clamp(360px, 28vw, 430px);
  max-width: 430px;
  margin: 0 auto;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto minmax(0, 1fr) auto auto;
  gap: 12px;
  align-items: stretch;
  padding: 16px;
  border: 1px solid var(--canvas-border);
  border-radius: 26px;
  background: var(--canvas-panel-strong);
  box-shadow: none;
  backdrop-filter: blur(22px);
  pointer-events: auto;
}

.canvas-composer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(203, 213, 225, 0.74);
}

.canvas-composer-head div {
  display: grid;
  gap: 4px;
}

.canvas-composer-head span,
.canvas-composer-head small {
  color: var(--canvas-muted);
  font-size: 12px;
  line-height: 1.45;
}

.canvas-composer-head strong {
  color: var(--canvas-ink);
  font-size: 21px;
  line-height: 1.15;
}

.canvas-composer-ref-drop {
  position: relative;
  min-height: 130px;
  border: 1px dashed #cbd8e7;
  border-radius: 18px;
  background: #f8fbfd;
  padding: 12px;
  display: grid;
  grid-template-rows: auto auto minmax(62px, 1fr);
  gap: 8px;
}

.canvas-composer-ref-drop strong {
  color: var(--canvas-ink);
  font-size: 14px;
}

.canvas-composer-ref-drop > span,
.canvas-composer-result {
  color: var(--canvas-muted);
  font-size: 12px;
}

.canvas-composer-ref-drop.drag-over {
  border-color: rgba(47, 109, 183, 0.54);
  background: #eaf2fb;
}

.canvas-composer-refs {
  min-height: 66px;
  display: flex;
  align-items: center;
  gap: 7px;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 2px 0;
}

.canvas-composer-ref-empty {
  min-width: 100%;
  padding: 16px 10px;
  border: 1px dashed #d7e2ef;
  border-radius: 12px;
  color: #718097;
  text-align: center;
}

.canvas-composer-ref {
  position: relative;
  flex: 0 0 68px;
  width: 68px;
  height: 68px;
  padding: 0;
  border: 1px solid #d7e2ef;
  border-radius: 14px;
  background: #ffffff;
  overflow: hidden;
}

.canvas-composer-ref img,
.canvas-composer-ref video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
  border-radius: 0;
}

.canvas-composer-ref .infinite-card-audio {
  height: 100%;
  border-radius: 0;
  font-size: 12px;
}

.canvas-composer-ref > span {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 2px 4px;
  background: rgba(15, 23, 42, 0.58);
  color: #ffffff;
  font-size: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.canvas-composer-ref i {
  position: absolute;
  top: 3px;
  right: 3px;
  display: none;
  padding: 2px 4px;
  border-radius: 999px;
  background: rgba(220, 38, 38, 0.95);
  color: #ffffff;
  font-style: normal;
  font-size: 10px;
}

.canvas-composer-ref:hover i {
  display: block;
}

.canvas-composer-ref-drop .danger {
  position: absolute;
  top: 10px;
  right: 10px;
  min-height: 24px;
  padding: 0 8px;
  font-size: 11px;
}

.canvas-prompt-box {
  display: grid;
  gap: 6px;
  color: var(--canvas-ink);
  font-weight: 850;
}

.canvas-prompt-box textarea {
  min-height: 150px;
  border: 1px solid #d6e1eb;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.94);
  color: var(--canvas-ink);
  resize: vertical;
}

.canvas-generate-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  align-items: end;
}

.canvas-generate-options label {
  display: grid;
  gap: 5px;
  color: var(--canvas-muted);
  font-size: 12px;
  font-weight: 850;
}

.canvas-generate-options input,
.canvas-generate-options select {
  min-height: 36px;
  border: 1px solid #d6e1eb;
  border-radius: 12px;
  background: #ffffff;
  color: var(--canvas-ink);
}

.canvas-generate-options .primary {
  grid-column: 1 / -1;
  min-height: 42px;
  border-radius: 14px;
}

.canvas-composer-result {
  grid-column: 1 / -1;
  min-height: 40px;
  padding: 10px 12px;
  border: 1px solid #dbe7f0;
  border-radius: 14px;
  background: #f8fbfd;
}

.canvas-composer-result[data-tone="ok"] {
  border-color: #a9c8e8;
  background: #effaf5;
  color: #2f6db7;
}

.canvas-composer-result[data-tone="busy"] {
  border-color: #c5d8f3;
  background: #f1f6ff;
  color: #285c9b;
}

.canvas-composer-result[data-tone="error"] {
  border-color: #f4b9b1;
  background: #fff5f3;
  color: #b42318;
}

.infinite-canvas-toolbar-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 4px;
  scrollbar-width: thin;
}

.infinite-canvas-toolbar-actions > * {
  flex: 0 0 auto;
}

.canvas-toolbar-select {
  width: auto;
  min-width: 118px;
  min-height: 36px;
}

.infinite-canvas-stage {
  position: absolute;
  inset: 0;
  min-height: 0;
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: none;
  border: 0;
  border-radius: 0;
  background-color: var(--canvas-surface, #f8fbfd);
  background-image: var(--canvas-grid-image);
  background-size: var(--canvas-grid-size-current, 28px) var(--canvas-grid-size-current, 28px);
  cursor: default;
}

.infinite-canvas-stage.panning {
  cursor: grabbing;
}

.infinite-canvas-stage.hand-tool {
  cursor: grab;
}

.infinite-canvas-stage.insert-tool {
  cursor: copy;
}

.infinite-canvas-stage.drag-over {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 2px rgba(47, 109, 183, 0.18);
}

/* 变暗只由下面的 ::before 一层负责。原来这里还有一个 inset 0 0 0 9999px 的扩散阴影做同样的事 ——
   两层遮罩叠加,而 9999px 扩散的绘制面积极大,平移期每帧都在画。只保留 1px 的边框提示。 */
.infinite-canvas-stage.picking-reference {
  cursor: default;
  box-shadow: inset 0 0 0 1px rgba(47, 109, 183, 0.22);
}

.infinite-canvas-stage.picking-reference::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  /* 0.28 ≈ 原来「0.22 遮罩 + 0.08 inset 阴影」两层叠加的观感,现在一层做完 */
  background: rgba(15, 23, 42, 0.28);
  pointer-events: none;
}

.infinite-canvas-stage.picking-reference .infinite-canvas-links {
  opacity: 0.28;
}

.infinite-canvas-content {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
  z-index: 2;
  touch-action: none;
}

/* 只在平移/缩放交互期提合成层；落定后撤销，避免大型画布永久占用 GPU 纹理内存。 */
.infinite-canvas-stage.canvas-interacting .infinite-canvas-content {
  will-change: transform;
}

/* 入场/编辑期由父层直接跳过整棵内容子树；镜头只移动上方的单图预览，不让 100~1000 张卡
   参与高倍率重栅格。退出恢复的揭层被安排在镜头结束后的独立收尾阶段。 */
.infinite-canvas-stage.canvas-edit-entry-isolated .infinite-canvas-content {
  content-visibility: hidden !important;
}
.infinite-canvas-stage.canvas-edit-entry-isolated :is(.infinite-canvas-links, .infinite-canvas-group-layer) {
  visibility: hidden !important;
}
.infinite-canvas-stage.canvas-edit-entry-isolated .canvas-edit-dim {
  visibility: hidden;
}
.infinite-canvas-stage.canvas-editing .infinite-canvas-links {
  visibility: hidden !important;
}

/* 退出编辑:content-visibility 隔离恢复的首帧=整棵内容树重新光栅(全卡同帧砰现)+连线呼吸动画
   集体从零相位重启,视觉上像「整个画布扩散重绘」。恢复帧用一次短淡入遮成渐显——纯合成 opacity,
   不触发布局;class 由 finalizeCanvasEditSessionClose 挂上、340ms 后摘除。 */
.infinite-canvas-stage.canvas-edit-reveal :is(.infinite-canvas-content, .infinite-canvas-links, .infinite-canvas-group-layer) {
  animation: canvasEditRevealFade .38s ease-out both;
}
/* 前 35% 保持全透明:content-visibility 恢复的分块光栅化(视口中心先、边缘后=「扩散」)
   在不可见窗口内完成,之后整体渐显——否则淡入过程中仍能看到周边卡片一圈圈扩散着出现。 */
@keyframes canvasEditRevealFade { 0%, 35% { opacity: 0; } 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .infinite-canvas-stage.canvas-edit-reveal :is(.infinite-canvas-content, .infinite-canvas-links, .infinite-canvas-group-layer) { animation: none; }
}

/* 懒媒体下载期的占位中性底(JS 在 infiniteCanvasLoadLazyMedia 挂/摘):低饱和 slate 亮暗主题皆宜,
   替代刺眼的「白格子」;载入完成随 180ms 淡入一起摘掉,保活池复用的已载瓦片从不出现占位。 */
#infiniteCanvasContent .canvas-tile-loading {
  background: rgba(148, 163, 184, 0.16);
}

/* 重复网格只在静止/缩放跨阈值时栅格化；平移期按格距取模后只动 transform。
   固定 256px overscan + 以舞台原点(元素内 256px,256px)为缩放原点，保证长距离平移/连续缩放不露白边。 */
.infinite-canvas-grid {
  position: absolute;
  inset: -256px;
  z-index: 0;
  contain: strict;
  overflow: hidden;
  background-image: var(--canvas-grid-image);
  background-repeat: repeat;
  background-size: 28px 28px;
  background-position: 0 0;
  transform-origin: 256px 256px;
  will-change: auto;
  backface-visibility: hidden;
  pointer-events: none;
}

.infinite-canvas-stage.canvas-interacting .infinite-canvas-grid {
  will-change: transform;
}

.infinite-canvas-inline-panel-layer {
  position: absolute;
  inset: 0;
  z-index: 36;
  pointer-events: none;
}

.infinite-canvas-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  /* 舞台本身已经裁剪；SVG 再显式裁剪可阻止离屏长线把合成/光栅层撑到整张世界画布。 */
  overflow: hidden;
  contain: paint;
  pointer-events: none;
  /* 外层固定承担视口裁剪；平移只给内部 g，避免裁剪窗口一起移动后露空/断线。 */
}

.infinite-canvas-links :is(.ic-links-body, .ic-links-selected, .ic-links-pulse) {
  transform-origin: 0 0;
  transform-box: view-box;
  will-change: auto;
}

.infinite-canvas-stage.canvas-interacting .infinite-canvas-links :is(.ic-links-body, .ic-links-selected, .ic-links-pulse) {
  will-change: transform;
}

/* 视口移动期间取消跨卡 hover/过渡和非必要流光；卡片、网格、连线都已经由父层合成移动。
   这只在 pointer capture 的 panning 窗口生效，松手下一帧恢复完整视觉。 */
.infinite-canvas-stage.panning .infinite-canvas-content {
  pointer-events: none;
}

.infinite-canvas-stage.canvas-interacting .infinite-card {
  transition-duration: 0s !important;
}

/* 交互开关只能命中卡片根节点。历史上的 `.infinite-card *` 会在开始/结束一次
   平移或缩放时让整张画布的所有后代重新匹配样式；百张富媒体卡会形成明显的
   首帧尖峰。真正需要冻结的持续动画在下方显式列出，拖动卡本身另由
   data-canvas-dragging 关闭 transform 过渡。 */

.infinite-canvas-stage.canvas-interacting #infiniteCanvasLinks .ic-links-pulse {
  display: none;
}

.infinite-canvas-stage.canvas-interacting :is(
  .infinite-card-run-progress-wave,
  .infinite-card-run-progress-wave path,
  .infinite-card-run-progress-bubble,
  .infinite-card-run-progress-glowband,
  .infinite-card-audio-wave i,
  .infinite-canvas-link.energized
) {
  animation-play-state: paused !important;
}

.infinite-canvas-active-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  overflow: hidden;
  contain: paint;
  pointer-events: none;
  display: none;
}

.infinite-canvas-active-links.is-active {
  display: block;
}

.infinite-canvas-link-active-drag {
  pointer-events: none;
  filter: none !important;
  animation: none !important;
  stroke-opacity: 1;
}

/* 拖动中的相邻线由 #infiniteCanvasActiveLinks 独立承载当前帧。持久 SVG 的 selected/pulse
   装饰层按旧几何绘制,如果继续显示就会和 active 层叠出残线；这里整组隐藏,松手终绘后恢复。 */
.infinite-canvas-stage.canvas-card-dragging #infiniteCanvasLinks :is(.ic-links-selected, .ic-links-pulse) {
  display: none;
}

.infinite-canvas-stage.canvas-card-dragging #infiniteCanvasLinks .infinite-canvas-link.energized {
  animation-play-state: paused;
}

:root {
  --wire-fx-line: #7f8d9e;
  --wire-fx-line-selected: #007fc8;
  --wire-fx-active: #00a6e8;
  --wire-fx-pulse: #20dcff;
  --wire-fx-core: #ffffff;
  --wire-fx-glow: rgba(32, 220, 255, 0.24);
  --wire-fx-temp: #8aa8c8;
}

body.theme-dark:not(.auth-required) {
  --wire-fx-line: #98aabd;
  --wire-fx-line-selected: #77dfff;
  --wire-fx-active: #8af7ff;
  --wire-fx-pulse: #b8fbff;
  --wire-fx-core: #ffffff;
  --wire-fx-glow: rgba(184, 251, 255, 0.24);
  --wire-fx-temp: #8ea4c0;
}

.infinite-canvas-link {
  fill: none;
  stroke: var(--wire-fx-line, #6f91b8);
  stroke-width: calc(2.4px * var(--canvas-link-zoom, 1));
  stroke-opacity: 0.68;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: stroke;
  cursor: pointer;
}

.infinite-canvas-link-hit {
  fill: none;
  stroke: rgba(47, 109, 183, 0.001);
  stroke-width: 14.67;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: stroke;
  cursor: pointer;
}

.infinite-canvas-link:hover,
.infinite-canvas-link.hovered,
.infinite-canvas-link.selected,
.infinite-canvas-link.energized {
  stroke: var(--wire-fx-line-selected, #3478a6);
  stroke-width: calc(2.85px * var(--canvas-link-zoom, 1));
  stroke-opacity: 1;
}

/* 选中模块 → 线本体保持细;流光改为每条线独立 SVG 渐变,用固定屏幕像素周期流动。
   多层低透明度渐变叠加,亮部更白,边界不再有 dash 硬切。 */
.infinite-canvas-link.energized {
  filter: none;
  animation: infinite-canvas-rail-breathe 2200ms ease-in-out infinite;
}

.infinite-canvas-links .ic-links-selected path,
.infinite-canvas-links .ic-links-pulse path {
  pointer-events: none !important;
}

.infinite-canvas-links .ic-links-selected .infinite-canvas-selected-link-base {
  stroke: var(--wire-fx-active, #00a6e8);
  stroke-width: calc(3.35px * var(--canvas-link-zoom, 1));
  stroke-opacity: 0.98;
  filter: drop-shadow(0 0 calc(2.8px * var(--canvas-link-zoom, 1)) var(--wire-fx-glow, rgba(32, 220, 255, 0.24)));
}

.infinite-canvas-link-pulse,
.infinite-canvas-link-pulse-silk,
.infinite-canvas-link-pulse-glow,
.infinite-canvas-link-pulse-veil {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
  stroke-dasharray: none;
  stroke-dashoffset: 0;
}
.infinite-canvas-link-pulse-veil {
  stroke-width: calc(7.2px * var(--canvas-link-zoom, 1));
  opacity: 0.28;
  filter: blur(calc(1.15px * var(--canvas-link-zoom, 1)));
}
.infinite-canvas-link-pulse-glow {
  stroke-width: calc(4.25px * var(--canvas-link-zoom, 1));
  opacity: 0.58;
  filter: blur(calc(0.42px * var(--canvas-link-zoom, 1)));
}
.infinite-canvas-link-pulse-silk {
  stroke-width: calc(2.35px * var(--canvas-link-zoom, 1));
  opacity: 0.9;
  filter: blur(calc(0.16px * var(--canvas-link-zoom, 1)));
}
.infinite-canvas-link-pulse {
  stroke-width: calc(1.24px * var(--canvas-link-zoom, 1));
  opacity: 1;
  filter: none;
}
@keyframes infinite-canvas-rail-breathe {
  0%, 100% { stroke-opacity: 0.96; }
  50% { stroke-opacity: 1; }
}
/* 视口交互(平移/缩放)期间选中装饰整组隐藏:pulse 四层带 blur/drop-shadow、selected 基线组
   是加粗线,合成层平移露新条带时每帧重光栅,40 条选中线可把帧时翻倍(38ms,profile 实测)。
   body 层的 energized 提亮线仍在=选中高亮不丢,松手恢复完整装饰。 */
.infinite-canvas-stage.canvas-interacting .infinite-canvas-links :is(.ic-links-pulse, .ic-links-selected) { display: none; }
.infinite-canvas-stage.canvas-interacting .infinite-canvas-links path.energized {
  filter: none !important;
  animation-play-state: paused !important;
}
/* 拖卡热路径克隆线(active-drag 层每帧改 d):永不带滤镜/流光动画——blur×每帧 d 变=每帧重光栅整层 */
.infinite-canvas-link-active-drag {
  filter: none !important;
  animation: none !important;
}
@media (prefers-reduced-motion: reduce) {
  .infinite-canvas-link.energized,
  .infinite-canvas-link-pulse,
  .infinite-canvas-link-pulse-silk,
  .infinite-canvas-link-pulse-glow,
  .infinite-canvas-link-pulse-veil { animation: none; }
}

.infinite-canvas-link-temp {
  fill: none;
  stroke: var(--wire-fx-temp, #8aa8c8);
  stroke-width: 2;
  stroke-dasharray: 7 6;
  stroke-linecap: round;
}

.infinite-canvas-link-temp-dot {
  fill: color-mix(in srgb, var(--wire-fx-line-selected, #3478a6) 16%, transparent);
  stroke: color-mix(in srgb, var(--wire-fx-line-selected, #3478a6) 58%, transparent);
  stroke-width: 2;
  pointer-events: none;
}

.infinite-canvas-link-temp-dot-core {
  fill: var(--wire-fx-line-selected, #3478a6);
  stroke: #ffffff;
  stroke-width: 1.5;
  pointer-events: none;
}

.infinite-canvas-selection-box {
  position: absolute;
  z-index: 5;
  border: var(--canvas-selection-frame-line-width) dashed var(--canvas-selection-frame-color);
  background: var(--canvas-selection-frame-fill);
  border-radius: var(--canvas-selection-frame-radius);
  box-shadow: inset 0 0 0 1px var(--canvas-selection-frame-inset);
  pointer-events: none;
  contain: layout style paint;
  backface-visibility: hidden;
}

.infinite-canvas-drop-hint {
  position: absolute;
  left: 98px;
  bottom: 82px;
  padding: 8px 12px;
  border: 1px solid #d6e1eb;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.86);
  color: var(--canvas-muted);
  pointer-events: none;
}

.canvas-empty-starters {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: none;
  place-items: center;
  pointer-events: none;
}

.infinite-canvas-stage[data-render-state="ready"][data-empty="true"] .canvas-empty-starters {
  display: grid;
}

.infinite-canvas-stage:is([data-render-state="loading"], [data-render-state="rendering"]) .canvas-empty-starters {
  display: grid;
}

.infinite-canvas-stage:is([data-render-state="loading"], [data-render-state="rendering"]) .canvas-empty-starters > * {
  display: none;
}

.canvas-empty-starters::before {
  display: none;
  padding: 14px 18px;
  border: 1px solid var(--canvas-border);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.9);
  color: var(--canvas-muted);
  font-weight: 800;
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.09);
  backdrop-filter: blur(16px);
}

.infinite-canvas-stage:is([data-render-state="loading"], [data-render-state="rendering"]) .canvas-empty-starters::before {
  content: "画布加载中...";
  display: block;
}

/* 未登录:画布内容已在渲染层置空(缓存保留),空态不再诱导"添加模块",改为统一登录引导卡(.guest-gate)。 */
body.account-guest #infiniteCanvasStage .canvas-empty-starters > *:not(.guest-gate) {
  display: none !important;
}
body.account-guest #infiniteCanvasStage .canvas-empty-starters {
  display: grid;
}
body.account-guest #infiniteCanvasStage .canvas-empty-starters .guest-gate {
  display: flex;
}

/* 未登录:无限画布是登录后才能用的功能。展示层已在渲染层清空,这里把工作区控件锁住(禁交互 + 置灰),
   避免游客对本地缓存数据动手(清空/下载/排列/生成等);舞台仅禁交互不置灰,居中保留登录引导。 */
body.account-guest #infiniteCanvasTab .canvas-creator-bar,
body.account-guest #infiniteCanvasTab .infinite-canvas-inspector,
body.account-guest #infiniteCanvasTab .canvas-corner-hud {
  pointer-events: none;
  opacity: 0.5;
}
body.account-guest #infiniteCanvasTab #infiniteCanvasStage {
  pointer-events: none;
}
body.account-guest #infiniteCanvasStage .canvas-empty-starters,
body.account-guest #infiniteCanvasStage .canvas-empty-starters .guest-gate,
body.account-guest #infiniteCanvasStage .canvas-empty-starters .guest-gate-login {
  pointer-events: auto;
}
body.account-guest #infiniteCanvasStage .canvas-empty-starters .guest-gate {
  position: absolute;
  left: 50%;
  top: 45%;
  z-index: 5;
  transform: translate(-50%, -50%);
}

/* 未登录:工作流同样是登录后功能。画布本体随 currentWorkflow=null 已清空,名称/说明在渲染层补清,
   这里锁住工具栏/侧栏/HUD(禁交互 + 置灰),并把空态提示改为引导登录,与无限画布保持一致。 */
body.account-guest #workflowTab .workflow-toolbar,
body.account-guest #workflowTab .workflow-sidebar,
body.account-guest #workflowTab .workflow-corner-hud {
  pointer-events: none;
  opacity: 0.5;
}
body.account-guest #workflowTab .workflow-stage-wrap {
  pointer-events: none;
}
body.account-guest #workflowEmptyState {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  padding: 0 !important;
  max-width: none !important;
  width: auto;
  z-index: 5;
  pointer-events: auto;
}
body.account-guest #workflowEmptyState .workflow-empty-hint {
  display: none;
}
body.account-guest #workflowEmptyState .guest-gate {
  display: flex;
}
body.account-guest #workflowEmptyState .guest-gate,
body.account-guest #workflowEmptyState .guest-gate-login {
  pointer-events: auto;
}

/* ---- 统一登录引导卡(工作流 / 无限画布共用):渐变图标徽章 + 标题 + 一句副文 + 登录按钮 ---- */
.guest-gate {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  box-sizing: border-box;
  width: 264px;
  padding: 22px 22px 18px;
  border: 1px solid color-mix(in srgb, var(--border, #e3e8f0) 85%, transparent);
  border-radius: 16px;
  background: color-mix(in srgb, var(--panel, #fff) 94%, transparent);
  box-shadow: 0 14px 36px -18px rgba(15, 23, 42, 0.16);
  backdrop-filter: blur(14px);
  text-align: center;
  pointer-events: auto;
  font-size: 13px;
  line-height: 1.6;
}

.guest-gate-icon {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  margin-bottom: 6px;
  background: linear-gradient(135deg, #4b86dd, #7a5fd0);
  box-shadow: 0 8px 16px -8px rgba(87, 111, 214, 0.55);
}

.guest-gate-icon svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.guest-gate strong {
  font-size: 14px;
  font-weight: 800;
  color: var(--text, #1c2433);
}

.guest-gate p {
  margin: 0;
  font-size: 12px;
  line-height: 1.65;
  color: var(--muted, #7a8699);
}

.guest-gate .guest-gate-login {
  margin-top: 12px;
  height: 32px;
  padding: 0 22px;
  border: none;
  border-radius: 9px;
  background: linear-gradient(135deg, #3d7bd4, #6a55c8);
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 8px 16px -8px rgba(87, 111, 214, 0.6);
  transition: transform 0.15s ease, filter 0.15s ease;
}

.guest-gate .guest-gate-login:hover {
  filter: brightness(1.07);
}

.guest-gate .guest-gate-login:active {
  transform: translateY(1px);
}

/* 暗色(卡族基准 #1b1f28/#454c5c;渐变钮防全局暗色 button 压平,选择器带元素名再断言) */
body.theme-dark:not(.auth-required) .guest-gate {
  background: rgba(27, 31, 40, 0.92);
  border-color: #454c5c;
  box-shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.6);
}
body.theme-dark:not(.auth-required) button.guest-gate-login {
  background: linear-gradient(135deg, #4d85d6, #7a5fd0);
  color: #fff;
  border: none;
}

.canvas-empty-card {
  width: min(560px, calc(100% - 180px));
  padding: 22px;
  border: 1px solid var(--canvas-border);
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: none;
  backdrop-filter: blur(18px);
  text-align: center;
  pointer-events: auto;
}

.canvas-empty-card > span {
  display: block;
  color: #2f6db7;
  font-size: 12px;
  font-weight: 900;
}

.canvas-empty-card > strong {
  display: block;
  margin-top: 6px;
  color: #0f172a;
  font-size: 24px;
  line-height: 1.25;
}

.canvas-empty-actions {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-top: 18px;
}

.canvas-empty-actions button {
  min-height: 44px;
  border: 1px solid #d6e4ef;
  border-radius: 14px;
  background: #f8fbff;
  color: #1f3454;
  font-weight: 900;
  cursor: pointer;
}

.canvas-empty-actions button:hover {
  border-color: rgba(47, 109, 183, 0.4);
  background: #eaf2fb;
}

.infinite-card {
  position: absolute;
  width: 240px;
  min-height: 124px;
  border: 1px solid #d6e0ec;
  border-radius: 18px;
  background: var(--card-fill, #ffffff);
  /* 性能:38px 大模糊阴影画起来很贵(每张卡片一份,增删/选中/移动都要重绘整片模糊)。
     收到 16px 并略提不透明度,视觉接近、绘制成本大幅下降——画布操作更流畅。 */
  box-shadow: 0 6px 16px rgba(31, 49, 79, 0.16);
  overflow: visible;
  user-select: none;
  touch-action: none;
  z-index: 2;
  color: var(--text);
  /* 布局/样式隔离:卡内变化(textarea 撑高、媒体载入)不再让整个画布层参与失效计算;
     卡是绝对定位,layout 包含不改变任何现有定位/尺寸行为(非 size 包含,高度仍由内容撑)。 */
  contain: layout style;
}

.infinite-card :is(input, textarea, select, button, a, [contenteditable="true"]),
.infinite-card-inline-panel :is(input, textarea, select, button, a, [contenteditable="true"]) {
  touch-action: manipulation;
}

.infinite-card[data-canvas-shape="rect"] {
  border-radius: 4px;
}

.infinite-card[data-canvas-shape="pill"] {
  border-radius: 26px;
}

.infinite-card[data-canvas-shape="ellipse"] {
  border-radius: 999px;
}

.infinite-card[data-canvas-shape="ellipse"] .infinite-card-head {
  border-radius: 999px 999px 0 0;
  justify-content: center;
}

.infinite-card[data-canvas-type="section"] {
  background: rgba(248, 251, 253, 0.58);
  border: 2px dashed rgba(47, 109, 183, 0.36);
  box-shadow: none;
}

.infinite-card[data-canvas-type="shape"] {
  box-shadow: 0 8px 22px rgba(31, 49, 79, 0.08);
}

.infinite-card[data-canvas-type="shape"] .infinite-card-body {
  min-height: 72px;
  display: grid;
  place-items: center;
  color: #475467;
}

.infinite-card[data-canvas-type="section"] {
  z-index: 1;
}

.infinite-card[data-canvas-type="section"] .infinite-card-head {
  background: rgba(100, 116, 139, 0.92);
}

.infinite-card[data-canvas-type="reference"] .infinite-card-body,
.infinite-card[data-canvas-type="result"] .infinite-card-body {
  min-height: 160px;
}

.infinite-card.grouped {
  outline: 2px dashed rgba(47, 109, 183, 0.22);
  outline-offset: 3px;
}

.infinite-card.search-hit {
  box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.32), 0 12px 30px rgba(31, 49, 79, 0.14);
}

.infinite-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(47, 109, 183, 0.2), 0 12px 30px rgba(31, 49, 79, 0.14);
}

/* 无限画布运行态只保留卡内定位；进度条视觉直接复用全站 site-generation-progress 契约。 */
.infinite-card.running {
  border-color: color-mix(in srgb, var(--card-accent, #2f6db7) 34%, #d9e6f2);
}
.infinite-card .infinite-card-run-progress { display: none; }
.infinite-card.running .infinite-card-run-progress {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
  gap: 4px;
  position: absolute;
  inset: auto 12px 12px;
  z-index: 7;
  height: auto;
  min-height: 0;
  padding: 0;
  overflow: visible;
  pointer-events: none;
  background: transparent;
}

/* 卡内轨道只负责定位，视觉完全由全站组件类提供。 */
.infinite-card-run-progress-track {
  order: 2;
  width: 100%;
  flex: 0 0 var(--generation-progress-height);
}
.infinite-card-run-progress-label {
  order: 1;
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  min-height: 0;
  padding: 2px 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.82);
  color: var(--muted);
  font-size: 11px;
  line-height: 1.3;
  white-space: nowrap;
}
.infinite-card-run-progress-pct {
  font-size: inherit;
  font-weight: 700;
}
.infinite-card-run-progress-pct:empty {
  display: none;
}
.infinite-card-run-progress-eta { font-size: inherit; font-weight: 600; }

/* ── 生成运行态·一体化液面(2026-07 定稿;7-13「统一进度」提交误把视觉一并简化,2026-07-21 按用户要求回归) ──
   视觉=微磨砂薄纱 + 强调色水体从左向右推进 + 双层波形前缘(流动=translateY 无缝循环,活=d:path 同相位胖瘦呼吸)
   + 玻璃药丸(pct/ETA)。数据仍由统一进度源驱动:--run-progress-pct 由 infiniteCanvasApplyRunProgress 写入。
   仅生成运行态启用;媒体上传态(media-ingress-active)保持底部细条不受影响。水体类名 waterfill(不能叫 fill,
   会被统一条的 .infinite-card-run-progress-fill 选择器逮走)。 */
.infinite-card-run-progress-water { display: none; }
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress {
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 0;
  inset: 0;
  height: auto;
  min-height: 0;
  border-radius: inherit;
  overflow: hidden;
  padding: 14px;
  isolation: isolate;
  background: rgba(240, 244, 250, 0.4); /* 整卡薄纱 0.4(2026-07-21 用户调参台定稿) */
}
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-track { display: none; }
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-water {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0.78; /* 2026-07-21 用户用调参台(样式馆 v2.1)定稿的一组参数,整组透明度统一在这里 */
  pointer-events: none;
}
/* 水体主体:不透明矩形,右缘塞进前景波形的实心区下面 3px(不透明压盖,无缝)。 */
.infinite-card-run-progress-waterfill {
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 2;
  width: calc(max(var(--run-progress-pct, 8%), 18px) - 11px);
  min-width: 6px;
  background: color-mix(in srgb, var(--card-accent, #2f6db7) 75%, #eef5fc);
  border-radius: inherit;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  pointer-events: none;
  overflow: hidden; /* 气泡的裁剪容器:漂出水面右缘即被吞掉 */
  transition: width 900ms cubic-bezier(0.22, 0.8, 0.28, 1);
}
/* 波形条 = 1.5 倍卡高的周期正弦(viewBox 0 0 28 150,λ=50,整 3 个周期)。⚠️ d:path() 形变是本区域
   对"只许 transform/opacity"的唯一豁免(重绘只在 28px 细竖条内);不支持 d 插值的浏览器降级为静态曲线。 */
.infinite-card-run-progress-wave {
  position: absolute;
  top: 0;
  left: calc(max(var(--run-progress-pct, 8%), 18px) - 14px + var(--wave-shift, 0px));
  width: 28px;
  height: 150%;
  z-index: 1;
  overflow: visible;
  pointer-events: none;
  transition: left 900ms cubic-bezier(0.22, 0.8, 0.28, 1);
}
/* 前景波形 = 主水的波浪右缘:与水体同色压顶。⚠️ 不许加 translateX(会把压盖关系晃出缝);translateY 安全。 */
.infinite-card-run-progress-wave.wave-front {
  z-index: 3;
  animation: infiniteCanvasWaveTravel 3.3s linear infinite;
}
.infinite-card-run-progress-wave.wave-front path {
  fill: color-mix(in srgb, var(--card-accent, #2f6db7) 75%, #eef5fc);
  animation: infiniteCanvasLineMorphA 3.4s ease-in-out infinite;
}
/* 背景波形 = 第二层水:反相+振幅更大+错后 8px+流速不同(波峰时隐时现的灵动感)。 */
.infinite-card-run-progress-wave.wave-back {
  --wave-shift: 5px;
  z-index: 1;
  -webkit-mask: linear-gradient(90deg, transparent 0, #000 12px);
  mask: linear-gradient(90deg, transparent 0, #000 12px);
  animation: infiniteCanvasWaveTravel 6.7s linear infinite;
}
.infinite-card-run-progress-wave.wave-back path {
  fill: color-mix(in srgb, var(--card-accent, #2f6db7) 52%, #cfe8ff);
  animation: infiniteCanvasLineMorphB 5.4s ease-in-out -2s infinite;
}
/* 流动:平移自身高度 1/3(=恰好一个波长)后回起点,周期图形→完全无缝。 */
@keyframes infiniteCanvasWaveTravel {
  from { transform: translateY(-33.333%); }
  to { transform: translateY(0); }
}
/* 呼吸:同相位胖/瘦正弦(锚点半波距+Hermite 镜像柄,数学生成),只变振幅→全程 C1 平滑无折角。
   改形状只能按公式整组重生成(x=14±A·1.0472 于控制点),别手调单个数字。 */
@keyframes infiniteCanvasLineMorphA {
  0%, 100% { d: path("M14 0 C21.33 8.33 21.33 16.67 14 25 C6.67 33.33 6.67 41.67 14 50 C21.33 58.33 21.33 66.67 14 75 C6.67 83.33 6.67 91.67 14 100 C21.33 108.33 21.33 116.67 14 125 C6.67 133.33 6.67 141.67 14 150 L0 150 L0 0 Z"); }
  50% { d: path("M14 0 C18.4 8.33 18.4 16.67 14 25 C9.6 33.33 9.6 41.67 14 50 C18.4 58.33 18.4 66.67 14 75 C9.6 83.33 9.6 91.67 14 100 C18.4 108.33 18.4 116.67 14 125 C9.6 133.33 9.6 141.67 14 150 L0 150 L0 0 Z"); }
}
@keyframes infiniteCanvasLineMorphB {
  0%, 100% { d: path("M14 0 C5.62 8.33 5.62 16.67 14 25 C22.38 33.33 22.38 41.67 14 50 C5.62 58.33 5.62 66.67 14 75 C22.38 83.33 22.38 91.67 14 100 C5.62 108.33 5.62 116.67 14 125 C22.38 133.33 22.38 141.67 14 150 L0 150 L0 0 Z"); }
  50% { d: path("M14 0 C8.97 8.33 8.97 16.67 14 25 C19.03 33.33 19.03 41.67 14 50 C8.97 58.33 8.97 66.67 14 75 C19.03 83.33 19.03 91.67 14 100 C8.97 108.33 8.97 116.67 14 125 C19.03 133.33 19.03 141.67 14 150 L0 150 L0 0 Z"); }
}
/* ── 灵动层(2026-07-21 用户调参台定稿:水线流光 0.44/波节光珠 0/气泡 0.68/体积光带 0.08) ──
   一体铁律:光效必须长在波形 SVG 里或水体裁剪内随波走,禁止再摆独立竖列(会读成拼缝竖线)。 */
/* 水线流光:开放路径描边,与前景波形同一组相位的胖瘦呼吸(结构 M+6C,闭合版的去尾镜像),
   随整条 SVG 平移=光贴着真实波形曲线流动。non-scaling-stroke 抵消 svg 纵向拉伸。 */
.infinite-card-run-progress-wave.wave-front path.infinite-card-run-progress-waveline {
  fill: none;
  stroke: color-mix(in srgb, var(--card-accent, #2f6db7) 20%, #ffffff);
  stroke-width: 1.7;
  opacity: 0.44;
  animation: infiniteCanvasLineMorphAS 3.4s ease-in-out infinite;
}
@keyframes infiniteCanvasLineMorphAS {
  0%, 100% { d: path("M14 0 C21.33 8.33 21.33 16.67 14 25 C6.67 33.33 6.67 41.67 14 50 C21.33 58.33 21.33 66.67 14 75 C6.67 83.33 6.67 91.67 14 100 C21.33 108.33 21.33 116.67 14 125 C6.67 133.33 6.67 141.67 14 150"); }
  50% { d: path("M14 0 C18.4 8.33 18.4 16.67 14 25 C9.6 33.33 9.6 41.67 14 50 C18.4 58.33 18.4 66.67 14 75 C9.6 83.33 9.6 91.67 14 100 C18.4 108.33 18.4 116.67 14 125 C9.6 133.33 9.6 141.67 14 150"); }
}
/* 气泡:纯从左往右随水流漂(2026-07-21 用户二次点名去掉上浮),漂出水面右缘被 waterfill 裁剪吞掉。
   dot 画在细列上的 --bub-y 高度,列 translateX 穿场=纯合成器动画;每颗的错位节奏在模板内联(时长/延迟/横漂距/高度)。 */
.infinite-card-run-progress-bubble {
  position: absolute;
  top: 0;
  height: 100%;
  width: 10px;
  background: radial-gradient(circle 4px at 50% var(--bub-y, 78%), rgba(255, 255, 255, 0.9), color-mix(in srgb, var(--card-accent, #2f6db7) 20%, #ffffff) 50%, transparent 100%);
  opacity: 0;
  pointer-events: none;
  animation: infiniteCanvasBubbleDrift 6s linear infinite;
}
@keyframes infiniteCanvasBubbleDrift {
  0% { transform: translateX(-14px); opacity: 0; }
  16% { opacity: 0.68; }
  84% { opacity: 0.34; }
  100% { transform: translateX(var(--bub-dx, 72px)); opacity: 0; }
}
/* 体积光带:波前一条极淡的宽软光(对称渐变无硬线),呼吸与前波同周期。 */
.infinite-card-run-progress-glowband { display: none; }
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-glowband {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  width: 26px;
  left: calc(max(var(--run-progress-pct, 8%), 18px) - 13px);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--card-accent, #2f6db7) 22%, #ffffff), transparent);
  pointer-events: none;
  animation: infiniteCanvasGlowBreath 3.4s ease-in-out infinite;
  transition: left 900ms cubic-bezier(0.22, 0.8, 0.28, 1);
}
@keyframes infiniteCanvasGlowBreath {
  0%, 100% { opacity: 0.036; }
  50% { opacity: 0.08; }
}
/* 减动效:保留分层静态观感,只停波动与灵动层。 */
@media (prefers-reduced-motion: reduce) {
  .infinite-card-run-progress-wave,
  .infinite-card-run-progress-wave path,
  .infinite-card-run-progress-bubble,
  .infinite-card-run-progress-glowband {
    animation: none !important;
  }
  .infinite-card-run-progress-glowband { opacity: 0.06; }
}
/* 玻璃药丸(液面态专属;上传态细条的 label 保持紧凑样式) */
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-label {
  order: 0;
  position: relative;
  z-index: 2;
  align-self: center;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 8px;
  max-width: calc(100% - 24px);
  min-height: 34px;
  padding: 8px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.64);
  box-shadow:
    0 10px 24px -12px rgba(30, 64, 100, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
  color: color-mix(in srgb, var(--card-accent, #2f6db7) 56%, #243247);
  text-align: center;
  white-space: nowrap;
  font-size: 12px;
}
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-pct {
  font-size: 15px;
  font-weight: 860;
  letter-spacing: 0;
  line-height: 1;
}
.infinite-card.running:not(.media-ingress-active) .infinite-card-run-progress-eta {
  font-size: 12px;
  font-weight: 720;
  opacity: 0.86;
}
.infinite-card-run-progress-label[hidden],
.infinite-card-run-progress-label:not(:has(.infinite-card-run-progress-pct:not(:empty), .infinite-card-run-progress-eta:not(:empty))) {
  display: none;
}

/* ── 缩小 LOD 档的生成进度细条:语义 LOD 模板从源头不建液面 DOM(性能取舍),此前缩小后
   「生成中」完全不可见。细条与液面共读卡根上的同一 --run-progress-pct(infiniteCanvasApplyRunProgress
   写在卡根,detail 液面与 LOD 细条谁在场谁消费),纯宽度过渡,无新增动画负担。 */
.infinite-card-lod-run {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 6px;
  height: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--card-accent, #2f6db7) 16%, rgba(255, 255, 255, 0.72));
  overflow: hidden;
  pointer-events: none;
  z-index: 3;
}
.infinite-card-lod-run-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  width: max(var(--run-progress-pct, 8%), 12%);
  background: linear-gradient(90deg, color-mix(in srgb, var(--card-accent, #2f6db7) 82%, #dbeafe), var(--card-accent, #2f6db7));
  transition: width 900ms cubic-bezier(0.22, 0.8, 0.28, 1);
}

/* 外部媒体导入与生成共用同一张卡、同一条 activity 进度轨道；只通过令牌换成橙色，
   不进入 running/generating 业务状态，避免误触发生成限制与陈旧任务回收。 */
.infinite-card.media-ingress-active {
  --generation-progress-fill: linear-gradient(90deg, #c2410c, #f59e0b);
  border-color: color-mix(in srgb, #f59e0b 48%, #d9e6f2);
}

.infinite-card.media-ingress-active .infinite-card-run-progress {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
  gap: 4px;
  position: absolute;
  inset: auto 12px 12px;
  z-index: 8;
  pointer-events: none;
}

.infinite-card.media-ingress-error {
  border-color: rgba(180, 35, 24, 0.48);
}

.infinite-media-ingress-preview {
  position: relative;
  display: block !important;
  width: 100%;
  height: 100%;
  min-height: 0;
  overflow: hidden;
  border-radius: inherit;
  background: #eef3f9;
  cursor: default;
}

.infinite-media-ingress-preview > :is(img, video) {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) saturate(0.18) brightness(0.94);
  opacity: 0.72;
  transition: filter 180ms ease, opacity 180ms ease;
}

.infinite-media-ingress-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, #f4f6f9, #e7edf4);
  color: #94a3b8;
}

.infinite-media-ingress-fallback span {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid rgba(100, 116, 139, 0.2);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.66);
  font-size: 20px;
  font-weight: 800;
}

.infinite-media-ingress-shade {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(145deg, rgba(194, 65, 12, 0.54), rgba(245, 158, 11, 0.4));
}

.infinite-media-ingress-preview:is(.is-queued, .is-checking, .is-uploading, .is-finalizing)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.42) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: infiniteCardResultShimmer 1.25s linear infinite;
  pointer-events: none;
}

.infinite-media-ingress-preview.is-finalizing .infinite-media-ingress-shade {
  opacity: 0.45;
}

.infinite-media-ingress-preview.is-error .infinite-media-ingress-shade {
  background: rgba(180, 35, 24, 0.34);
}

.infinite-media-ingress-copy {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 5px;
  padding: 22px;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 4px rgba(15, 23, 42, 0.42);
  pointer-events: none;
}

.infinite-media-ingress-copy strong {
  font-size: 13px;
  font-weight: 800;
}

.infinite-media-ingress-copy span {
  max-width: 100%;
  overflow: hidden;
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-media-ingress-actions {
  position: absolute;
  left: 50%;
  bottom: 18px;
  z-index: 9;
  display: flex;
  gap: 7px;
  transform: translateX(-50%);
}

.infinite-media-ingress-actions[hidden] {
  display: none !important;
}

.infinite-media-ingress-actions button {
  min-width: 58px;
  border: 1px solid rgba(255, 255, 255, 0.66);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.9);
  color: #b42318;
  font-size: 12px;
  font-weight: 800;
  padding: 6px 9px;
  cursor: pointer;
  box-shadow: 0 3px 10px rgba(15, 23, 42, 0.18);
}

.infinite-target-ingress-thumb {
  position: relative;
  width: 78px;
  min-width: 78px;
  height: 92px;
  margin: 2px;
  overflow: hidden;
  border: 1px solid rgba(194, 65, 12, 0.34) !important;
  border-radius: 10px;
  background: #fffaf5 !important;
  --upload-accent: #ea580c;
}

.infinite-target-ingress-thumb .reference-upload-status {
  display: block;
  min-height: 22px;
  padding: 3px 5px;
  overflow: hidden;
  color: #9a3412;
  font-size: 9px;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-target-ingress-actions {
  position: absolute;
  inset: auto 3px 26px;
  z-index: 8;
  display: flex;
  justify-content: center;
  gap: 3px;
}

.infinite-target-ingress-actions[hidden] {
  display: none !important;
}

.infinite-target-ingress-actions button {
  min-width: 0;
  border: 1px solid rgba(255, 255, 255, 0.78);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.94);
  color: #b42318;
  font-size: 9px;
  font-weight: 800;
  padding: 3px 5px;
}

.infinite-playlist-box > .infinite-target-ingress-thumb,
.infinite-card-media-box > .infinite-target-ingress-thumb,
#canvasComposerRefs > .infinite-target-ingress-thumb {
  display: inline-flex;
  vertical-align: top;
}

@media (prefers-reduced-motion: reduce) {
  .infinite-media-ingress-preview::after {
    animation: none !important;
  }
}

/* 多张结果：这一个模块「展开」= 在画布上铺开的多个子模块卡（每张自带「图片生成」标题头 + 图片体）。
   点某张=设为主图并收起；生成中的空格显示同款卡壳 + 骨架占位。外层卡透明，子卡之间露出画布网格，像铺开的多个模块。 */
.infinite-card.result-grid-card {
  position: absolute;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  overflow: visible;
  pointer-events: none;
}
.infinite-card.result-grid-card .infinite-card-head {
  position: absolute;
  z-index: 8;
  top: -38px;
  bottom: auto;
  left: 0;
  right: auto;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  width: var(--result-cell-w, calc((100% - var(--result-col-gap, 18px)) * 0.5)); /* 只占第一格宽 → flex-end 让收起按钮落在「第一张图片」的右上角，和折叠态一致 */
  max-width: none;
  min-height: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  color: var(--card-accent, #2f6db7);
  pointer-events: none;
}
.infinite-card.result-grid-card .infinite-card-head > :not(.infinite-card-results-toggle) {
  display: none;
}
.infinite-card.result-grid-card .infinite-card-body { padding: 0; overflow: visible; }
/* 多结果网格态：整卡进度条一律隐藏（改用每个生成中子卡各自的底部进度条）；即便 .running 被直接 toggle 到网格卡也不冒大条。 */
.infinite-card.result-grid-card .infinite-card-run-progress { display: none !important; }
.infinite-card-result-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--result-col-gap, 18px);
  row-gap: var(--result-row-gap, 34px);
  overflow: visible;
  /* 每格按自己图片比例定高（body 上 inline aspect-ratio）；align-items:start 让矮格保持本高、靠行顶，不被拉伸变形。 */
  align-items: start;
  /* 只有格子(图片+标签)可拖，格子间隙/隐藏大框不拖；touch-action:none 让格子上的拖动不被手机端滚动抢走。 */
  touch-action: none;
}
/* 每张结果 = 一张真正的画布模块：标题浮在图片上方，卡身只画图片/占位。 */
.infinite-card-result-module {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  overflow: visible;
  /* 格子=图片+标签：既可点选主图又可拖动整组，用 grab 提示「这里能拖」。 */
  cursor: grab;
  pointer-events: auto;
  text-align: left;
  color: var(--text);
  font: inherit;
  user-select: none;
  -webkit-user-drag: none;
  appearance: none;
  transition: transform 0.14s ease;
}
.infinite-card-result-module:active { cursor: grabbing; }
.infinite-card-result-module.generating { cursor: default; }
.infinite-card-result-module-head {
  position: absolute;
  left: 0;
  right: 0;
  top: auto;
  bottom: calc(100% + 3px);
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 5px;
  height: 20px;
  padding: 0 2px;
  color: var(--card-accent, #2f6db7);
  font-size: 13px;
  line-height: 18px;
}
.infinite-card-result-module-head strong {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--card-accent, #2f6db7);
  font-weight: 900;
}
.infinite-card-result-module-badge {
  display: grid;
  place-items: center;
  width: 14px;
  height: 14px;
  border-radius: 0;
  background: transparent;
  color: var(--card-accent, #2f6db7);
  flex: 0 0 14px;
}
.infinite-card-result-module-badge svg { width: 12px; height: 12px; }
.infinite-card-result-module-tag {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--card-accent, #2f6db7);
  color: #ffffff;
  font-size: 10px;
  font-weight: 800;
  line-height: 16px;
}
.infinite-card-result-module-body {
  position: relative;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 100%;
  aspect-ratio: var(--result-cell-aspect, 1);
  border: 1px solid #d6e0ec;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 8px 18px rgba(31, 49, 79, 0.12);
  overflow: hidden;
}
.infinite-card-result-module-body img,
.infinite-card-result-module-body video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: none;
  background: #eef3f9;
  pointer-events: none;
}
.infinite-card-result-module:hover {
  transform: translateY(-1px);
}
.infinite-card-result-module:hover .infinite-card-result-module-body {
  border-color: color-mix(in srgb, var(--card-accent, #2f6db7) 45%, #cfe0f0);
  box-shadow: 0 10px 24px rgba(31, 49, 79, 0.16);
}
.infinite-card-result-module.main .infinite-card-result-module-body {
  border-color: var(--card-accent, #2f6db7);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--card-accent, #2f6db7) 20%, transparent), 0 6px 16px rgba(31, 49, 79, 0.14);
}
.infinite-card-result-module-body.generating {
  background: #ffffff;
}
/* 生成中占位微光:静底 + ::after 斜光带 translateX 扫过(合成器动画)。
   原来动 background-position——多张结果并行生成时一排大卡同时每帧重绘。 */
.infinite-card-result-skeleton {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #eef3f9;
}
.infinite-card-result-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.72) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: infiniteCardResultShimmer 1.25s linear infinite;
}
@keyframes infiniteCardResultShimmer {
  to { transform: translateX(100%); }
}
.infinite-card-result-ph {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 9px;
}
.infinite-card-result-ph-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: linear-gradient(150deg, color-mix(in srgb, var(--card-accent, #2f6db7) 22%, #fff) 0%, color-mix(in srgb, var(--card-accent, #2f6db7) 9%, #fff) 100%);
  color: var(--card-accent, #2f6db7);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--card-accent, #2f6db7) 16%, transparent);
}
.infinite-card-result-ph-icon svg { width: 24px; height: 24px; }
.infinite-card-result-ph-text {
  font-size: 12px;
  font-weight: 700;
  color: color-mix(in srgb, var(--card-accent, #2f6db7) 60%, #64748b);
}
/* 生成中子卡只保留卡内定位；轨道/填充复用全站生成进度条视觉令牌。 */
.infinite-card-result-progress {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 2;
}
/* 生成模块头部「收起/展开这组结果」小药丸：和模块名同高的内联按钮，右上角。 */
.infinite-card-results-toggle {
  flex: 0 0 auto;
  margin-left: auto; /* 折叠态:把「展开结果」按钮推到卡头右上角，和展开态「收起结果」同一位置 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 28px;
  padding: 4px 10px;
  border: 1px solid color-mix(in srgb, var(--card-accent, #2f6db7) 28%, transparent);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.94);
  color: var(--card-accent, #2f6db7);
  font-size: 12px;
  font-weight: 800;
  line-height: 17px;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(31, 49, 79, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.88);
  transition: background 0.14s ease, border-color 0.14s ease;
}
.infinite-card-results-toggle:hover {
  border-color: color-mix(in srgb, var(--card-accent, #2f6db7) 46%, transparent);
  background: #ffffff;
}
.infinite-card-results-toggle-icon {
  display: inline-grid;
  place-items: center;
  color: var(--card-accent, #2f6db7);
}
.infinite-card-results-toggle-icon svg { display: block; }
.infinite-card-results-count {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--card-accent, #2f6db7);
  color: #ffffff;
  font-size: 11px;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
}
/* 展开态：头部透明浮在画布上，只需让药丸可点；样式与折叠态「展开结果」按钮完全一致（收起/展开长一个样）。 */
.infinite-card.result-grid-card .infinite-card-results-toggle {
  pointer-events: auto;
}
.infinite-card.result-grid-card .infinite-card-results-count {
  background: var(--card-accent, #2f6db7);
  color: #ffffff;
}

/* 可选卡的强调:只用 outline + 一圈实心描边阴影。
   ⚠️ 别加大模糊阴影(原来是 0 22px 48px)和 per-card transform(原来 scale(1.015)):
   拾取态下**所有**媒体卡都带这套样式,平移时内容层整体 transform,每张卡的大模糊阴影都要重新
   光栅化、独立 transform 又打断整层合成 —— 实测 106 模块的画布上平移 p95 从 16.8ms 劣化到 33.3ms、
   掉帧从 2 涨到 7。outline + 0 扩散阴影视觉上一样是「高亮可选」,但不产生模糊绘制。 */
.infinite-card.media-pickable {
  opacity: 1;
  outline: 2px solid rgba(47, 109, 183, 0.84);
  outline-offset: 7px;
  cursor: pointer;
  filter: none;
  box-shadow: 0 0 0 5px rgba(47, 109, 183, 0.14);
}

.infinite-card.media-pick-target {
  outline: 2px dashed rgba(47, 109, 183, 0.48);
  outline-offset: 5px;
}

/* 「这张不能选」只由这一条表达,两个主题共用,浓度靠 --canvas-pick-dim 一个旋钮(暗色在 part2 调)。
   ⚠️ 实现必须是「盖一层同底色蒙版」,不能是 opacity / filter:
   那两者都要求浏览器先把整张卡的子树渲染成独立纹理再做混合,拾取态下几十张卡 = 几十个渲染面,
   平移时每有新瓦片进视口就得重栅格化一遍。实测 106 模块的画布上,这一条会让平移在 60fps 和 30fps 之间反复跳。
   蒙版是一次普通的矩形绘制,没有渲染面,视觉几乎一样。 */
.infinite-canvas-stage.picking-reference {
  --canvas-pick-dim: 70%;
}
.infinite-canvas-stage.picking-reference .infinite-card:not(.media-pickable):not(.media-pick-target)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 6;
  border-radius: inherit;
  background: color-mix(in srgb, var(--canvas-surface, #f8fbfd) var(--canvas-pick-dim, 70%), transparent);
  pointer-events: none;
}

.infinite-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 9px 11px;
  background: var(--card-accent, #2f6db7);
  color: #ffffff;
  cursor: default;
}

.infinite-card-link-handle {
  position: relative;
  width: 24px;
  height: 24px;
  border: 2px solid rgba(255, 255, 255, 0.86);
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.58);
  cursor: crosshair;
  flex: 0 0 24px;
  /* 只留柔和落影,去掉 0 0 0 10px 的扩散环——那圈光晕让连接点像被「框住」,视觉很难受。 */
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.18);
}

/* 「+」用两条小横/竖杠画,而不是文字 content:"+"——文字的 + 受字体度量影响、视觉上不在正中(用户反馈「加号不在中间」)。
   两条定长杠按 top/left:50% + translate(-50%,-50%) 居中,与字体无关、永远正中。 */
.infinite-card-link-handle::before,
.infinite-card-link-handle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: #ffffff;
  border-radius: 1px;
  pointer-events: none;
}
.infinite-card-link-handle::before {
  width: 11px;
  height: 2.4px;
  transform: translate(-50%, -50%);
}
.infinite-card-link-handle::after {
  width: 2.4px;
  height: 11px;
  transform: translate(-50%, -50%);
}

.infinite-card-head > .infinite-card-link-handle {
  display: none;
}

.infinite-card-link-zone {
  /* 圆形定点热区：以连接点为圆心、垂直居中卡片边，clip-path 让响应区域真正是圆形（圆外不触发）。 */
  position: absolute;
  top: 50%;
  z-index: 6;
  display: grid;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  clip-path: circle(50%);
  place-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.infinite-card-link-zone.left {
  /* 圆心离卡片边约 40px → 连接点圆边离卡片约一个圆的距离 */
  left: -68px;
  transform: translate(-8px, -50%);
}

.infinite-card-link-zone.right {
  right: -68px;
  transform: translate(8px, -50%);
}

.infinite-card:hover .infinite-card-link-zone,
.infinite-card.selected .infinite-card-link-zone,
.infinite-card-link-zone:focus-within,
.infinite-card-link-zone:has(.infinite-card-link-handle:hover),
.infinite-card-link-zone:has(.infinite-card-link-handle.linking) {
  opacity: 1;
  transform: translate(0, -50%);
}

.infinite-card-link-zone::before {
  content: "";
  position: absolute;
  inset: 0 4px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.015);
}

.infinite-card-link-zone .infinite-card-link-handle {
  pointer-events: auto;
}

.infinite-card-link-handle:hover {
  background: rgba(37, 90, 156, 0.78);
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.22); /* hover 也不要 0 0 0 13px 扩散环 */
}

.infinite-card-link-handle.linking {
  opacity: 0;
  transform: scale(0.72);
}

/* 磁吸时连接点会朝光标平移(--link-magnet-x/y)且放大(scale 1.08),对角方向会越过热区的 circle(50%) 裁切线
   → 连接点被裁成「水滴/缺角」。磁吸期间去掉 clip-path,让连接点完整显示(此时本就在拖连线、圆形热区可不要)。 */
.infinite-card-link-zone:has(.infinite-card-link-handle.magnetized) {
  clip-path: none !important;
  overflow: visible !important;
}

.infinite-card-head:active {
  cursor: default;
}

.infinite-card-head strong {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-card-badge {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.18);
  font-size: 13px;
  font-weight: 800;
}

.infinite-card-body {
  padding: 10px;
  color: var(--text);
}

.infinite-card-body textarea {
  width: 100%;
  min-height: 78px;
  resize: none;
  border: 1px solid #d7e2ef;
  border-radius: 8px;
  background: #ffffff;
  color: var(--text);
  padding: 8px;
  font: inherit;
}

/* 文本 / 提示词模块：输入框与模块框框合为一体——保留卡片本体的圆角描边，
   但去掉内部 textarea 的「框中框」边框、白底和右下角拖拽握把，整张卡片就是一个可直接输入的区域。
   卡片改成纵向 flex，让 textarea 撑满 head 以下的全部高度（随卡片缩放一起伸缩）。 */
.infinite-card[data-canvas-type="text"],
.infinite-card[data-canvas-type="prompt"] {
  display: flex;
  flex-direction: column;
}
.infinite-card[data-canvas-type="text"] .infinite-card-body,
.infinite-card[data-canvas-type="prompt"] .infinite-card-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding: 0;
}
.infinite-card[data-canvas-type="text"] .infinite-card-body .infinite-card-linked-text,
.infinite-card[data-canvas-type="prompt"] .infinite-card-body .infinite-card-linked-text {
  margin: 8px 12px 0;
}
/* 「来自连接的文本」连接指示块按用户要求整体隐藏:它本是「有参考图时 @ 参考图、标识当前描述对象」的雏形,功能未成形前先藏掉
   (顺带根治那个无尺寸 link 图标撑满容器变成超大链条的问题——见 contextMenuIconSvg 已补默认尺寸兜底)。
   连接进来的文本仍会在生成时并入提示词,只是不再显示这个指示条。 */
.infinite-card-linked-text { display: none !important; }
.infinite-card[data-canvas-type="text"] .infinite-card-body textarea,
.infinite-card[data-canvas-type="prompt"] .infinite-card-body textarea {
  flex: 1 1 auto;
  min-height: 88px;
  border: none !important;
  border-radius: 0 0 16px 16px;
  background: transparent !important;
  background-image: none !important;
  box-shadow: none !important;
  padding: 6px 13px 13px !important;
  resize: none !important;
}

.infinite-card-body input,
.infinite-card-body select {
  width: 100%;
  min-width: 0;
  min-height: 28px;
  border: 1px solid #d7e2ef;
  border-radius: 7px;
  background: #ffffff;
  color: var(--text);
  padding: 4px 7px;
  font: inherit;
}

/* ===== 内联编辑面板自定义下拉（替代原生 <select>，弹层自绘，夜间/日间一致）=====
   隐藏原生 select 仍承载 data-canvas-config 绑定，外观全由下面这套控件接管。 */
.infinite-card-cs {
  position: relative;
  width: 100%;
  min-width: 0;
}
.infinite-card-cs-native {
  display: none;
}
.infinite-card-cs-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-height: 28px;
  padding: 4px 9px;
  border: 1px solid #d7e2ef;
  border-radius: 7px;
  background: #ffffff;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  user-select: none;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.infinite-card-cs-trigger:hover {
  border-color: #b9cbe0;
}
.infinite-card-cs.cs-open .infinite-card-cs-trigger {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(47, 109, 183, 0.14);
}
.infinite-card-cs.is-disabled {
  opacity: 0.6;
}
.infinite-card-cs.is-disabled .infinite-card-cs-trigger {
  cursor: not-allowed;
}
.infinite-card-cs-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
  font-weight: inherit;
}
.infinite-card-cs.model-branded .infinite-card-cs-trigger {
  justify-content: center;
  padding-inline: 8px;
}
.infinite-card-cs.model-branded .infinite-card-cs-label {
  flex: 0 1 auto;
  display: flex;
  justify-content: flex-start;
  min-width: 0;
}
.infinite-card-cs-main {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: min(100%, 214px);
  min-width: 0;
}
.infinite-card-cs-main .model-logo {
  width: 19px;
  height: 19px;
  border-radius: 6px;
}
.infinite-card-cs-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.infinite-card-cs-caret {
  flex: 0 0 auto;
  color: #8497ab;
  transition: transform 140ms ease;
}
.infinite-card-cs.cs-open .infinite-card-cs-caret {
  transform: rotate(180deg);
}
.infinite-card-cs-pop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  z-index: 40;
  min-width: 100%;
  width: max-content;
  max-width: min(280px, 72vw);
  max-height: 248px;
  overflow-y: auto;
  padding: 6px;
  display: grid;
  gap: 2px;
  border: 1px solid rgba(202, 215, 229, 0.92);
  border-radius: 13px;
  background: #ffffff;
  box-shadow: 0 18px 46px rgba(15, 23, 42, 0.2);
  cursor: default;
  animation: qrPopIn 130ms ease;
}
.infinite-card-cs.cs-pop-below .infinite-card-cs-pop {
  bottom: auto;
  top: calc(100% + 8px);
}
.infinite-card-cs-pop[hidden] {
  display: none;
}
.infinite-card-cs-opt {
  padding: 7px 10px;
  border-radius: 9px;
  color: #2c3e52;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.infinite-card-cs-pop.model-select-pop {
  width: min(280px, max(100%, 72vw));
}
.infinite-card-cs-opt.has-model-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 7px 9px;
}
.infinite-card-cs-opt:hover {
  background: #eef3f8;
}
.infinite-card-cs-opt.active {
  background: #eaf2fb;
  color: var(--accent);
  font-weight: 800;
}

.infinite-card-fields {
  display: grid;
  gap: 7px;
}

.infinite-card-field {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  color: #4a5870;
  font-size: 12px;
}

.infinite-card-field span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-card-note {
  white-space: pre-wrap;
  line-height: 1.5;
  color: #2c3b50;
}

/* ===== 导演台 (Director Console) ===== */
.director-card { display: grid; gap: 8px; padding: 2px; }
.director-card-strip { display: flex; gap: 5px; overflow: hidden; }
.director-strip-cell {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  aspect-ratio: 16 / 10;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: #f5f7fa;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.director-strip-cell > span { font-size: 11px; font-weight: 800; color: var(--muted-2, #98a2b3); }
.director-strip-cell.has-img { border-color: transparent; }
.director-strip-cell.has-img > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.director-strip-cell.has-img > span { position: absolute; left: 3px; top: 2px; color: #fff; font-size: 10px; text-shadow: 0 1px 2px rgba(0,0,0,.6); z-index: 1; }
.director-strip-cell.director-strip-more { background: #eef2f7; color: #475569; font-weight: 800; font-size: 12px; }
.director-card-meta { font-size: 12px; color: var(--muted); }
.director-card-hint { font-size: 11.5px; color: var(--muted-2, #98a2b3); }

.director-console { display: grid; gap: 12px; }
.director-block { border: 1px solid var(--border); border-radius: 12px; background: #fbfcfe; padding: 11px 12px; display: grid; gap: 9px; }
.director-block-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; font-weight: 850; color: #344054; }
.director-block-head .director-count { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: #eef2f7; color: #475569; font-size: 11px; font-weight: 800; }
.director-add {
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: #eaf2fb;
  color: var(--accent-strong);
  font-weight: 750;
  font-size: 12px;
  padding: 4px 10px;
  cursor: pointer;
}
.director-add:hover { background: var(--accent); color: #fff; }
.director-field-col { display: grid; gap: 4px; font-size: 12px; color: #475569; min-width: 0; }
.director-field-col > textarea,
.director-field-col > select,
.director-cast-name,
.director-shot-prompt,
.director-shot-size { width: 100%; box-sizing: border-box; font-family: inherit; }
.director-field-col > textarea,
.director-shot-prompt { resize: vertical; border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; font-size: 13px; }
.director-grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.director-empty { font-size: 12.5px; color: var(--muted); padding: 10px; border: 1px dashed var(--border); border-radius: 8px; text-align: center; line-height: 1.6; }

.director-cast-list { display: grid; gap: 8px; }
.director-cast { border: 1px solid var(--border); border-radius: 10px; background: #fff; padding: 8px; display: grid; gap: 7px; }
.director-cast-thumbs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.director-cast-thumb { position: relative; width: 46px; height: 46px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.director-cast-thumb > img { width: 100%; height: 100%; object-fit: cover; }
.director-cast-thumb-del {
  position: absolute; right: 1px; top: 1px; width: 16px; height: 16px;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: rgba(16,24,40,.62); color: #fff; font-size: 10px; line-height: 1; cursor: pointer;
}
.director-cast-add-ref {
  width: 46px; height: 46px; border: 1px dashed var(--border); border-radius: 8px;
  background: #f7f9fc; color: var(--accent-strong); font-size: 12px; font-weight: 700; cursor: pointer;
}
.director-cast-add-ref:hover { border-color: var(--accent); background: #eaf2fb; }
.director-cast-row { display: flex; gap: 8px; align-items: center; }
.director-cast-name { flex: 1 1 auto; border: 1px solid var(--border); border-radius: 8px; padding: 6px 9px; font-size: 13px; }
.director-cast-del { flex: 0 0 auto; border: 1px solid #f1c4c0; border-radius: 8px; background: #fff; color: var(--danger); font-size: 12px; padding: 6px 10px; cursor: pointer; }
.director-cast-del:hover { background: var(--danger); color: #fff; }

.director-shot-list { display: grid; gap: 9px; }
.director-shot { border: 1px solid var(--border); border-radius: 10px; background: #fff; padding: 9px; display: grid; gap: 7px; transition: border-color .15s ease, box-shadow .15s ease; }
.director-shot.is-running { border-color: #b45309; box-shadow: 0 0 0 3px rgba(180,83,9,.12); }
.director-shot-head { display: flex; align-items: center; gap: 7px; }
.director-shot-no { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; border-radius: 6px; background: #b45309; color: #fff; font-size: 12px; font-weight: 800; }
/* .director-shot-head 前缀提特异度(0,2,0)，压过全局 .infinite-card-body select{width:100%}，否则景别下拉撑满整行把生成/删除挤出面板 */
.director-shot-head .director-shot-size { flex: 0 0 auto; width: auto; max-width: 40%; border: 1px solid var(--border); border-radius: 7px; padding: 4px 6px; font-size: 12px; }
.director-shot-run { flex: 1 1 auto; border: 1px solid var(--accent); border-radius: 7px; background: #eaf2fb; color: var(--accent-strong); font-weight: 750; font-size: 12.5px; padding: 5px 8px; cursor: pointer; }
.director-shot-run:hover:not(:disabled) { background: var(--accent); color: #fff; }
.director-shot-run:disabled { opacity: .55; cursor: default; }
.director-shot-mini { flex: 0 0 auto; width: 24px; height: 26px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 7px; background: #fff; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; }
.director-shot-mini:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-strong); }
.director-shot-mini:disabled { opacity: .4; cursor: default; }
.director-shot-del { flex: 0 0 auto; width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 7px; background: #fff; color: var(--muted); cursor: pointer; }
.director-shot-del:hover { border-color: var(--danger); color: var(--danger); }
.director-shot-cast { display: flex; flex-wrap: wrap; gap: 6px; }
.director-cast-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px; background: #f7f9fc; font-size: 12px; color: #475569; cursor: pointer; }
.director-cast-chip > input { width: auto; margin: 0; }
.director-cast-chip.on { border-color: #b45309; background: rgba(180,83,9,.1); color: #92400e; }
.director-shot-result { border-radius: 8px; overflow: hidden; border: 1px solid var(--border); background: #f5f7fa; min-height: 84px; display: grid; place-items: center; }
.director-shot-result > span { font-size: 12px; color: var(--muted-2, #98a2b3); }
.director-shot-result.has-img { border-color: transparent; min-height: 0; }
.director-shot-result.has-img > img { width: 100%; display: block; max-height: 280px; object-fit: contain; background: #0d1117; cursor: zoom-in; }
.director-run-bar { position: sticky; bottom: 0; padding-top: 2px; }
.director-run-all { width: 100%; }
.director-run-bar { display: flex; gap: 8px; }
.director-run-bar .secondary { flex: 0 0 auto; }
.director-run-bar .primary { flex: 1 1 auto; }

/* ===== 导演台 (3D 人偶台 poser) ===== */
.poser-card { display: grid; gap: 8px; padding: 2px; }
.poser-card-shot { aspect-ratio: 4 / 3; border-radius: 10px; border: 1px solid var(--border); background: linear-gradient(135deg,#efe7fb,#e6edf7); display: grid; place-items: center; overflow: hidden; }
.poser-card-shot > span { font-size: 12px; font-weight: 800; color: #7c3aed; }
.poser-card-shot.has-img { border-color: transparent; }
.poser-card-shot.has-img > img { width: 100%; height: 100%; object-fit: cover; }
/* 导演台折叠卡：和其它卡片一样是「圆角 + 柔光阴影」的卡（保留基础 box-shadow），只去掉描边和底部说明小字。
   卡身用 flex 纵向、快照撑满标题栏以下整块（避免 min-height 比内容高时白底露出一条白边）。
   关键：不能给整卡 overflow:hidden——会裁掉卡片外侧 -68px 的连接热区；所以直接给首/末子元素切圆角，
   让标题栏顶部 + 快照底部对齐卡片 18px 圆角，黑色预览不再是直角硬边、不再有「方框感」。链接热区/缩放手柄是 absolute，不受 flex 影响。 */
.infinite-card[data-canvas-type="poser"] { border: 0; display: flex; flex-direction: column; }
body.theme-dark:not(.auth-required) .infinite-card[data-canvas-type="poser"] { border: 0; }
.infinite-card[data-canvas-type="poser"] .infinite-card-head { border-radius: 18px 18px 0 0; }
.infinite-card[data-canvas-type="poser"] .infinite-card-body { padding: 0; flex: 1 1 auto; min-height: 0; }
.infinite-card[data-canvas-type="poser"] .poser-card { padding: 0; gap: 0; display: block; height: 100%; position: relative; }
/* width/height:100% 铺满卡身；object-fit:cover 填满。圆角收口:快照不再自带圆角——
   旧写死 0 0 18px 18px(卡片旧 18px 圆角遗留)与现卡身裁切(7px)不一致,会在底部两角露出下层"叠两层";
   统一交给卡身 .infinite-card-body(overflow:hidden + border-radius)这一个来源裁切,快照本身归零。 */
.infinite-card[data-canvas-type="poser"] .poser-card-shot { border: 0; width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
/* 悬浮「图片反推」胶囊按钮：默认隐藏，鼠标移到卡上(或卡被选中)才淡入上浮。位置固定锚在底部居中，不随重渲跳动。button 元素天然豁免卡片拖拽。 */
/* 居中用 left:0;right:0;margin:auto(而非 transform:translateX(-50%)) —— 全局 button:hover 的 translate3d(0,-1px,0)
   会顶掉 translateX(-50%) 让按钮横跳;改用 margin 居中后,那个全局抬升只作用垂直方向,不再横移。translateY 仅用于淡入上滑。 */
.poser-card-pose-btn { position: absolute; left: 0; right: 0; bottom: 12px; margin: 0 auto; width: fit-content; max-width: 86%; z-index: 4; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 14px; border: 0; border-radius: 999px; background: rgba(17,14,34,0.74); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); color: #fff; font-size: 12px; font-weight: 600; letter-spacing: 0.2px; cursor: pointer; white-space: nowrap; box-shadow: 0 8px 22px rgba(0,0,0,0.32); opacity: 0; pointer-events: none; transform: translateY(4px); transition: opacity 0.16s ease, transform 0.16s ease, background 0.16s ease; }
.infinite-card[data-canvas-type="poser"]:hover .poser-card-pose-btn,
.infinite-card[data-canvas-type="poser"].selected .poser-card-pose-btn { opacity: 1; pointer-events: auto; transform: translateY(0); }
.poser-card-pose-btn:hover { background: rgba(17,14,34,0.92); }
.poser-card-pose-btn:active { background: rgba(17,14,34,1); }

/* 导演台折叠卡「空态」设计:柔紫渐变 + 人偶线性图标 + 标题/副标 + 角标 3D(替代单行「3D 导演台」文字,好看些) */
.poser-card-shot.poser-card-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; position: relative;
  background: radial-gradient(130% 140% at 50% -20%, rgba(124,58,237,0.16), transparent 62%), linear-gradient(152deg,#f2ecfd 0%,#eaf0fb 55%,#f4eefc 100%); }
.poser-card-empty .poser-card-glyph { display: grid; place-items: center; line-height: 0; }
.poser-card-empty .poser-card-glyph svg { width: 28%; max-width: 54px; min-width: 30px; height: auto; color: #8b5cf6; opacity: 0.92; filter: drop-shadow(0 5px 12px rgba(124,58,237,0.2)); }
.poser-card-empty .poser-card-title { font-size: 13px; font-weight: 800; color: #6d28d9; letter-spacing: 0.4px; }
.poser-card-empty .poser-card-sub { font-size: 10.5px; font-weight: 600; color: #a08fc8; }
/* 空态提示:连全景图当背景。做成淡紫小药丸,和空态风格统一 */
.poser-card-empty .poser-card-tip { margin-top: 3px; font-size: 10px; font-weight: 600; color: #7c5cc9; background: rgba(124,58,237,0.09); border: 1px solid rgba(124,58,237,0.16); border-radius: 999px; padding: 3px 11px; max-width: 88%; text-align: center; line-height: 1.4; }
.poser-card-empty .poser-card-badge { position: absolute; top: 9px; left: 9px; font-size: 9.5px; font-weight: 900; letter-spacing: 0.6px; color: #fff;
  background: linear-gradient(135deg,#8b5cf6,#6d28d9); border-radius: 6px; padding: 1px 6px; box-shadow: 0 2px 6px rgba(109,40,217,0.32); }

/* 导演台「从画布中选择」全景背景下拉:挂在按钮父容器内(全屏 studio modal 之上),列出画布图片项 */
.poser-bg-picker { position: absolute; left: 0; right: 0; bottom: calc(100% + 6px); z-index: 30; max-height: 280px; overflow-y: auto;
  background: #fff; border: 1px solid var(--border, #e2e8f0); border-radius: 12px; box-shadow: 0 16px 40px rgba(15,23,42,0.22); padding: 6px; display: flex; flex-direction: column; gap: 3px; }
.poser-bg-pick-head { font-size: 11px; font-weight: 800; color: #64748b; padding: 4px 8px 6px; }
.poser-bg-pick-empty { font-size: 12px; color: #94a3b8; line-height: 1.6; padding: 10px; text-align: center; }
.poser-bg-pick-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 6px; border: 0; background: transparent; border-radius: 9px; cursor: pointer; text-align: left; }
.poser-bg-pick-item:hover { background: #f1f5fb; }
.poser-bg-pick-thumb { width: 46px; height: 30px; flex: 0 0 auto; border-radius: 6px; background: #e8eef6 center/cover no-repeat; border: 1px solid var(--border, #e2e8f0); }
.poser-bg-pick-name { font-size: 12.5px; font-weight: 600; color: #1f2937; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.poser-console { display: grid; gap: 10px; }
.poser-stage { position: relative; width: 100%; aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden; border: 1px solid var(--border); background: #eaeef3; touch-action: none; }
.poser-canvas { display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; overscroll-behavior: none; }
.poser-canvas:active { cursor: grabbing; }
/* 视口手势提示:居中悬浮暗色药丸(原来是横贯视口底部的灰条,又宽又抢戏) */
.poser-stage-hint { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); max-width: min(92%, 760px); width: max-content; text-align: center; font-size: 11.5px; line-height: 1.45; white-space: normal; word-break: break-word; color: #dfe9f6; background: rgba(15, 23, 42, 0.62); border-radius: 999px; padding: 6px 16px; pointer-events: none; z-index: 4; transition: opacity .45s ease, transform .45s ease; }
.poser-stage-hint.is-faded { opacity: 0; transform: translate(-50%, 6px); }
/* Three / 图片反推共用舞台进度层：轨道视觉复用全站 site-generation-progress，业务层只负责布局与状态文案。 */
.poser-runtime-overlay { position: absolute; inset: 0; z-index: 9; display: grid; place-items: center; padding: 20px; box-sizing: border-box; background: rgba(226, 232, 240, .76); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.poser-runtime-overlay[hidden] { display: none !important; }
.poser-runtime-card { width: min(390px, 92%); padding: 18px 20px; border: 1px solid rgba(148, 163, 184, .34); border-radius: 16px; background: rgba(255, 255, 255, .94); color: #1e293b; box-shadow: 0 18px 55px rgba(15, 23, 42, .18); }
.poser-runtime-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
.poser-runtime-head strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; font-weight: 800; }
.poser-runtime-head span { flex: 0 0 auto; color: #58667a; font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 800; }
.poser-runtime-track { width: 100%; height: 5px; }
.poser-runtime-meta { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 18px; margin-top: 9px; color: #64748b; font-size: 11.5px; font-variant-numeric: tabular-nums; }
.poser-runtime-meta span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; }
.poser-runtime-error { margin: 10px 0 0; color: #b42318; font-size: 12px; line-height: 1.45; word-break: break-word; }
.poser-runtime-retry { display: block; margin: 12px 0 0 auto; }
.poser-runtime-overlay.is-error { background: rgba(241, 245, 249, .86); }
.poser-toolbar { display: flex; flex-wrap: wrap; gap: 6px; }
.poser-tool { border: 1px solid var(--border); border-radius: 8px; background: #fff; color: #475569; font-size: 12px; font-weight: 700; padding: 5px 10px; cursor: pointer; }
.poser-tool:hover:not(:disabled) { border-color: #7c3aed; color: #7c3aed; background: #f6f3fe; }
.poser-tool:disabled { opacity: .5; cursor: default; }
.poser-tool.poser-tool-danger:hover:not(:disabled) { border-color: var(--danger); color: var(--danger); background: #fff5f4; }
.poser-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.poser-prompt { width: 100%; box-sizing: border-box; resize: vertical; border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; font-size: 13px; font-family: inherit; }
.poser-fields-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* auto-fit：宽面板 4 列一行，窄面板自动折成 2×2，按钮不挤压 */
.poser-mode-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); gap: 6px; }
.poser-mode { border: 1px solid var(--border); border-radius: 8px; background: #fff; color: #475569; font-size: 12.5px; font-weight: 700; padding: 6px 4px; cursor: pointer; }
.poser-mode:hover { border-color: #7c3aed; color: #7c3aed; }
.poser-mode.active { border-color: #7c3aed; background: #7c3aed; color: #fff; }
.poser-add-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.poser-add-label { font-size: 11.5px; color: #8a96a7; font-weight: 700; letter-spacing: .3px; }
/* .poser-add-row 前缀提特异度，压过全局 select{width:100%}，否则体型下拉撑满整行把添加按钮挤到下一行 */
.poser-add-row .poser-build-select { flex: 0 0 auto; width: auto; min-width: 92px; max-width: 132px; border: 1px solid var(--border); border-radius: 8px; background: #fff; color: #475569; font-size: 12px; font-weight: 700; padding: 5px 6px; cursor: pointer; }
.poser-add-row .poser-build-select:hover { border-color: #7c3aed; color: #7c3aed; }
/* 纵向 flex（不是 grid）——grid 的 auto 行在 flex:1 容器里会被 align-content 拉伸成 115px 巨高行 */
.poser-actor-list { display: flex; flex-direction: column; gap: 6px; max-height: 168px; overflow: auto; }
/* 一行制角色行(对齐机位列表风格)：圆点 + 名字 + 复制 + 删除；点行=选中对焦，双击名字=改名；体型/颜色改去右侧检视器 */
.poser-actor { display: flex; align-items: center; gap: 9px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 10px; background: #fff; cursor: pointer; transition: border-color .12s, background .12s; }
.poser-actor:hover { border-color: #c4b5fd; background: #faf8ff; }
.poser-actor.selected { border-color: #7c3aed; background: #f3effe; box-shadow: 0 0 0 1px #7c3aed inset; }
.poser-actor-dot { flex: 0 0 auto; width: 11px; height: 11px; border-radius: 50%; border: 1px solid rgba(0,0,0,.18); }
.poser-actor .poser-actor-name { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 650; color: #1f2a37; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.poser-actor-kind { flex: 0 0 auto; color: var(--muted); font-size: 11.5px; }
/* ✕/⧉ 幽灵按钮：平时无边框淡灰、不抢视线；悬停才显底色高亮 */
.poser-actor-dup, .poser-actor-del, .poser-shot-del { flex: 0 0 auto; width: 24px; height: 24px; min-height: 0; display: grid; place-items: center; border: 1px solid transparent; border-radius: 7px; background: transparent; color: #9aa7b8; cursor: pointer; font-size: 13px; padding: 0; transition: background .12s, color .12s, border-color .12s; }
.poser-actor-dup:hover { border-color: #e6def9; background: #f6f3fe; color: #7c3aed; }
.poser-actor-del, .poser-shot-del { font-size: 12px; }
.poser-actor-del:hover, .poser-shot-del:hover { border-color: #f3d9d6; background: #fff5f4; color: var(--danger); }
/* 就地改名输入框（角色行 / 机位行双击改名共用） */
.poser-rename-input { width: 100%; min-width: 0; border: 1px solid var(--poser-accent, #7c3aed); border-radius: 6px; background: #fff; padding: 2px 6px; font-size: 13px; font-weight: 650; color: #1f2a37; outline: none; box-sizing: border-box; }

/* —— 右侧「角色属性」数值检查器（参考 3D 编辑器：位置/旋转 XYZ + 统一缩放）—— */
.poser-inspector { display: flex; flex-direction: column; gap: 8px; }
.poser-insp-empty { color: var(--muted); font-size: 12px; padding: 4px 2px; }
.poser-insp-axis { display: grid; grid-template-columns: 36px repeat(3, minmax(0, 1fr)); align-items: center; gap: 6px; }
.poser-insp-axis-label { font-size: 12px; color: #475569; font-weight: 700; }
.poser-insp-cell { display: flex; align-items: center; gap: 4px; border: 1px solid var(--border); border-radius: 7px; background: #fff; padding: 0 7px; height: 30px; min-width: 0; }
.poser-insp-cell i { font-style: normal; font-size: 11px; font-weight: 800; color: #9aa6b6; white-space: nowrap; flex: 0 0 auto; }
.poser-insp-cell input { flex: 1 1 auto; width: 100%; min-width: 0; border: 0; background: transparent; font-size: 12px; color: #1f2a37; padding: 0; outline: none; }
.poser-insp-cell input::-webkit-outer-spin-button, .poser-insp-cell input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.poser-insp-scale { display: flex; align-items: center; gap: 9px; }
.poser-insp-scale input[type="range"] { flex: 1 1 auto; min-width: 0; accent-color: #7c3aed; }
.poser-insp-scale input[type="number"] { flex: 0 0 56px; width: 56px; height: 30px; border: 1px solid var(--border); border-radius: 7px; padding: 0 6px; font-size: 12px; text-align: center; color: #1f2a37; }
/* 角色检视：名字+颜色一行（第一行）*/
.poser-insp-head { display: flex; align-items: center; gap: 8px; }
.poser-insp-dot { flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%; box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--border); }
.poser-insp-name { flex: 1 1 auto; min-width: 0; height: 32px; border: 1px solid var(--border); border-radius: 8px; padding: 0 9px; font-size: 13px; font-weight: 600; color: #1f2a37; background: #fff; outline: none; }
.poser-insp-name:focus { border-color: #7c3aed; }
.poser-insp-color { flex: 0 0 auto; width: 34px; height: 32px; padding: 2px; border: 1px solid var(--border); border-radius: 8px; background: #fff; cursor: pointer; }
/* 角色属性面板：属性/姿势 Tab + 分段标签布局（名称/位置/旋转/缩放/统一缩放/颜色）*/
.poser-insp-tabs { display: flex; gap: 4px; margin-bottom: 2px; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
.poser-insp-tab { flex: 0 0 auto; border: 0; background: transparent; color: #64748b; font-size: 13px; font-weight: 750; padding: 5px 14px; border-radius: 8px; cursor: pointer; transition: background .12s, color .12s; }
.poser-insp-tab:hover { color: #7c3aed; background: rgba(124, 58, 237, .08); }
.poser-insp-tab.active { background: #7c3aed; color: #fff; }
.poser-insp-pane { display: flex; flex-direction: column; gap: 12px; }
.poser-insp-pane[hidden] { display: none; }
.poser-insp-field { display: flex; flex-direction: column; gap: 5px; }
.poser-insp-flabel { font-size: 12px; font-weight: 700; color: #64748b; }
.poser-insp-xyz { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.poser-insp-uni { display: flex; align-items: center; gap: 10px; }
.poser-insp-uni-slider { flex: 1 1 auto; min-width: 0; accent-color: #7c3aed; cursor: pointer; }
.poser-insp-uni-val { flex: 0 0 auto; min-width: 54px; text-align: center; height: 30px; line-height: 28px; border: 1px solid var(--border); border-radius: 7px; background: #fff; font-size: 12px; color: #1f2a37; }
.poser-insp-color-row { display: flex; align-items: center; gap: 8px; }
.poser-insp-colorhex { flex: 1 1 auto; min-width: 0; height: 32px; border: 1px solid var(--border); border-radius: 8px; padding: 0 10px; font-size: 12.5px; color: #1f2a37; background: #fff; outline: none; }
.poser-insp-colorhex:focus { border-color: #7c3aed; }
/* 场景·灯光·机位·环境：沿用 .poser-insp-field（标签在上+内容）布局，与属性面板统一 */
.poser-scene { display: flex; flex-direction: column; gap: 12px; }
.poser-scene .poser-field-2 { gap: 8px; }
.poser-insp-field > select, .poser-insp-field > input, .poser-insp-field > .poser-num { width: 100%; box-sizing: border-box; height: 32px; }
.poser-insp-field > .poser-tool { width: 100%; min-height: 32px; display: inline-flex; align-items: center; justify-content: center; }
.poser-insp-field .poser-pano-modes { margin: 0; }
.poser-insp-field .poser-hdr-row { margin-top: 0; }
/* 摆动作：图标按钮网格（不再用下拉折叠栏）*/
.poser-insp-pose-sec { display: flex; flex-direction: column; gap: 6px; }
.poser-insp-seclabel { font-size: 12px; font-weight: 700; color: #475569; }
.poser-pose-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.poser-pose-btn { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 7px 2px 4px; border: 1px solid var(--border); border-radius: 9px; background: #fff; color: #475569; cursor: pointer; transition: border-color .12s, color .12s, background .12s, transform .12s; }
.poser-pose-btn svg { width: 26px; height: 26px; }
.poser-pose-btn span { font-size: 10px; line-height: 1; color: #64748b; white-space: nowrap; }
.poser-pose-btn:hover { border-color: #7c3aed; color: #7c3aed; background: #f6f3ff; transform: translateY(-1px); }
.poser-pose-btn:hover span { color: #7c3aed; }
.poser-pose-btn:active { transform: translateY(0); }
.poser-pose-btn:first-child { border-color: #c4b5fd; background: #faf8ff; } /* 常规(站立) 轻微高亮 */
/* 动作两行可滚动：限高约两行、纵向滚动，省高度 */
.poser-pose-grid-2row { max-height: 96px; overflow-y: auto; overflow-x: hidden; padding: 2px 4px 2px 2px; }
.poser-pose-grid-2row::-webkit-scrollbar { width: 6px; }
.poser-pose-grid-2row::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
/* 自定义动作 / 新建 / 删除 / 拖拽排序 */
.poser-pose-btn { position: relative; touch-action: none; }
.poser-insp-hint { font-size: 10px; font-weight: 500; color: #94a3b8; margin-left: 7px; }
.poser-pose-custom { border-color: #f3cd9a; background: #fffaf2; }
.poser-pose-custom:hover { border-color: #ef9d4e; color: #d97a18; background: #fff6ea; }
.poser-pose-del { position: absolute; top: -5px; right: -5px; width: 15px; height: 15px; line-height: 14px; text-align: center; font-size: 10px; font-style: normal; color: #fff; background: #f0a04b; border-radius: 50%; opacity: 0; transition: opacity .12s, background .12s; box-shadow: 0 1px 3px rgba(0,0,0,.22); }
.poser-pose-custom:hover .poser-pose-del { opacity: 1; }
.poser-pose-del:hover { background: #e8554e; }
.poser-pose-new { border-style: dashed; color: #7c3aed; border-color: #c4b5fd; background: #faf8ff; }
.poser-pose-new:hover { border-color: #7c3aed; background: #f3eeff; }
.poser-pose-new svg { width: 22px; height: 22px; }
.poser-pose-btn.poser-pose-dragging { opacity: .28; }
.poser-pose-btn.poser-drop-left { box-shadow: inset 3px 0 0 #7c3aed; }
.poser-pose-btn.poser-drop-right { box-shadow: inset -3px 0 0 #7c3aed; }
.poser-pose-ghost { position: fixed; z-index: 99999; pointer-events: none; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 7px 2px 4px; border: 1px solid #7c3aed; border-radius: 9px; background: #fff; color: #7c3aed; opacity: .94; box-shadow: 0 10px 26px rgba(80,40,160,.32); transform: scale(1.07); }
.poser-pose-ghost svg { width: 26px; height: 26px; }
.poser-pose-ghost span { font-size: 10px; line-height: 1; color: #7c3aed; }
.poser-pose-ghost .poser-pose-del { display: none; }
/* 动作命名弹窗 */
.poser-posename-overlay { position: fixed; inset: 0; z-index: 100000; background: rgba(15,18,28,.42); display: flex; align-items: center; justify-content: center; }
.poser-posename-card { width: 264px; background: #fff; border-radius: 14px; padding: 18px; box-shadow: 0 20px 54px rgba(0,0,0,.3); }
.poser-posename-title { font-size: 14px; font-weight: 700; color: #1e293b; margin-bottom: 12px; }
.poser-posename-input { width: 100%; box-sizing: border-box; padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px; font-size: 13px; outline: none; }
.poser-posename-input:focus { border-color: #7c3aed; box-shadow: 0 0 0 3px rgba(124,58,237,.13); }
.poser-posename-err { color: #e8554e; font-size: 11px; margin-top: 6px; }
.poser-posename-btns { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
.poser-posename-btns button { padding: 7px 16px; border-radius: 8px; font-size: 13px; cursor: pointer; border: 1px solid var(--border); background: #fff; color: #475569; }
.poser-posename-btns .poser-posename-cancel:hover { background: #f1f5f9; }
.poser-posename-btns .poser-posename-ok { background: #7c3aed; color: #fff; border-color: #7c3aed; }
.poser-posename-btns .poser-posename-ok:hover { background: #6d28d9; }
/* 位置/旋转/缩放 折叠区 */
.poser-insp-fold { border: 1px solid var(--border); border-radius: 10px; padding: 4px 8px 8px; background: #fbfcfe; }
.poser-insp-fold > summary { cursor: pointer; list-style: none; padding: 4px 0; user-select: none; }
.poser-insp-fold > summary::-webkit-details-marker { display: none; }
.poser-insp-fold > summary::before { content: "▾"; display: inline-block; width: 14px; color: #94a3b8; transition: transform .15s; }
.poser-insp-fold:not([open]) > summary::before { transform: rotate(-90deg); }
.poser-insp-fold > .poser-insp-axis { margin-top: 6px; }
/* 焦距/光圈等数值输入(替代滑块) */
.poser-num { width: 100%; height: 30px; border: 1px solid var(--border); border-radius: 7px; padding: 0 8px; font-size: 12px; color: #1f2a37; background: #fff; outline: none; }
.poser-num:focus { border-color: #7c3aed; }
/* 全景模式切换按钮 720°/柱状 */
.poser-pano-modes { display: flex; gap: 6px; margin: 4px 0 6px; }
.poser-pano-modes button { flex: 1 1 0; }
.poser-pano-modes button.active { border-color: #7c3aed; background: #f3effe; color: #7c3aed; font-weight: 700; }
.poser-pano-modes button:disabled { opacity: 0.45; cursor: not-allowed; }
/* 全景背景调整(旋转)行 */
.poser-pano-adjust { margin-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.poser-pano-adjust[hidden] { display: none; }
.poser-pano-rot-label { font-size: 11.5px; color: #64748b; font-weight: 600; display: flex; justify-content: space-between; }
.poser-pano-rot-label b { color: #7c3aed; font-weight: 800; }
.poser-pano-adjust input[type="range"] { width: 100%; accent-color: #7c3aed; }
/* 可滑动数值：滚轮 / 左右拖动调整，光标提示左右拖 */
.poser-scrub { cursor: ew-resize; }
.poser-scrub:focus { cursor: text; }

/* —— 左栏「机位」：保存的相机设置列表 —— */
.poser-shot-add { border: 1px solid var(--border); background: #fff; color: #475569; font-size: 12px; font-weight: 700; padding: 3px 11px; border-radius: 999px; cursor: pointer; transition: border-color .12s, color .12s; }
.poser-shot-add:hover { border-color: #7c3aed; color: #7c3aed; }
.poser-shot-list { display: flex; flex-direction: column; gap: 5px; }
.poser-shot-empty { color: var(--muted); font-size: 11.5px; line-height: 1.5; padding: 0 2px 2px; }
.poser-shot { display: flex; align-items: center; gap: 9px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 10px; background: #fff; cursor: pointer; transition: border-color .12s, background .12s; }
.poser-shot:hover { border-color: #c4b5fd; background: #faf8ff; }
.poser-shot-ico { flex: 0 0 auto; color: #f2a23a; display: inline-flex; }
.poser-shot-name { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 650; color: #1f2a37; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* .poser-shot-del 尺寸/幽灵样式与 .poser-actor-del 合并在上方统一规则里 */
/* 进入中的机位高亮 + 实时标记；自由视角行 */
.poser-shot.selected { border-color: #7c3aed; background: #f3effe; box-shadow: 0 0 0 1px #7c3aed inset; }
.poser-shot-live { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: #16a34a; }
.poser-shot-free .poser-shot-ico { color: #64748b; }
.poser-fit-btn { width: 100%; }
/* 焦距 / 光圈滑块 */
label.director-field-col input[type="range"] { width: 100%; accent-color: #7c3aed; }
[data-poser-mm-val], [data-poser-fstop-val], [data-poser-laz-val], [data-poser-lel-val], [data-poser-lint-val] { color: #7c3aed; font-weight: 700; }

/* ============ 图片编辑台（Image Studio）：AI Photoshop 式全屏编辑器，浮动按钮 + 满幅工作区 ============ */
/* 配色统一走站点 token（浅色基调 + 品牌渐变强调 + 无限画布同款网格底），theme-dark 自动切暗 */
.image-studio-mask { padding: 0; }
/* 进出编辑台的丝滑过渡：整体淡入 + 轻微放大；关闭淡出。过渡挂在遮罩(modal-mask 不受全站禁用 transition 影响) */
#imageStudioModal { transition: opacity .22s ease, transform .24s cubic-bezier(.16, 1, .3, 1); transform-origin: center; }
#imageStudioModal:not(.is-open) { opacity: 0; transform: scale(.992); }
#imageStudioModal.is-open { opacity: 1; transform: none; }
#imageStudioModal.is-closing { opacity: 0; transform: scale(.992); }
.image-studio-panel {
  width: 100vw; max-width: none; height: 100dvh; max-height: none;
  border-radius: 0; padding: 0; overflow: hidden;
}
.image-studio {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  background: var(--bg); color: var(--text);
}
/* 满幅工作区 + 无限画布同款网格底（透明区可见） */
.image-studio-stage {
  position: absolute; inset: 0; overflow: hidden; touch-action: none; cursor: default;
  background-color: var(--studio-canvas-surface-light);
  background-image: var(--studio-canvas-grid-image-light);
}
body.theme-dark .image-studio-stage {
  background-color: var(--studio-canvas-surface-dark);
  background-image: var(--studio-canvas-grid-image-dark);
}
.image-studio-stage.is-panning { cursor: grabbing; }
.image-studio-canvas {
  position: absolute; top: 0; left: 0;
  box-shadow: 0 6px 28px rgba(38, 52, 92, .22);
}
.image-studio-loading {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 5;
  background: color-mix(in srgb, var(--bg) 72%, transparent); color: var(--muted); font-size: 14px;
}
.image-studio-loading[hidden] { display: none; }
/* 浮动面板通用底（白色卡片 + 站点描边 + 弹层阴影） */
.image-studio-rail,
.image-studio-options,
.image-studio-topright,
.image-studio-zoom,
.image-studio-aipanel {
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-popover);
}
/* 浮动：左侧工具栏 */
.image-studio-rail {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%); z-index: 10;
  display: flex; flex-direction: column; gap: 4px; padding: 8px; border-radius: var(--radius-lg);
}
.image-studio-tool {
  display: grid; grid-template-rows: auto auto; gap: 3px; justify-items: center;
  width: 60px; padding: 8px 4px; border: 0; border-radius: var(--radius-md); cursor: pointer;
  background: transparent; color: var(--muted); transition: background .15s, color .15s;
}
.image-studio-tool:hover { background: var(--surface-3); color: var(--text); }
.image-studio-tool.is-active { background: var(--brand-gradient); color: #fff; box-shadow: var(--brand-glow); }
.image-studio-tool-ico { display: inline-grid; place-items: center; }
.image-studio-tool-ico svg { width: 20px; height: 20px; }
.image-studio-tool-label { font-size: 11px; font-weight: 650; letter-spacing: .2px; }
/* 浮动：顶部选项条（随工具变） */
.image-studio-options {
  position: absolute; top: 16px; left: 50%; transform: translateX(-50%); z-index: 9;
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 7px 16px;
  border-radius: var(--radius-lg); color: var(--text); max-width: min(64vw, 720px);
}
.image-studio-options-hint { font-size: 13px; color: var(--muted); }
/* 浮动：右上 撤回/重做/关闭 */
.image-studio-topright {
  position: absolute; top: 16px; right: 16px; z-index: 11;
  display: flex; align-items: center; gap: 6px; padding: 6px; border-radius: var(--radius-lg);
}
.image-studio-iconbtn {
  display: inline-grid; place-items: center; width: 36px; height: 36px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--muted); cursor: pointer; transition: background .15s, color .15s;
}
.image-studio-iconbtn svg { width: 19px; height: 19px; }
.image-studio-iconbtn:hover:not(:disabled) { background: var(--surface-3); color: var(--text); }
.image-studio-iconbtn:disabled { opacity: .4; cursor: default; }
.image-studio-close:hover:not(:disabled) { background: var(--danger-soft); color: #d92d20; }
.image-studio-sep { width: 1px; height: 22px; background: var(--border); margin: 0 2px; }
/* 浮动：右侧 AI 面板（仅 AI 类工具显示） */
.image-studio-aipanel {
  position: absolute; top: 74px; right: 16px; width: 300px; max-height: calc(100dvh - 168px); overflow: auto; z-index: 9;
  padding: 16px; border-radius: var(--radius-lg); color: var(--text);
}
.image-studio-aipanel[hidden] { display: none; }
/* 浮动：底部 缩放 + 保存 */
.image-studio-foot {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 10;
  display: flex; align-items: center; gap: 12px;
}
.image-studio-zoom {
  display: inline-flex; align-items: center; gap: 4px; padding: 5px 8px; border-radius: var(--radius-md);
}
.image-studio-zoom-btn {
  min-width: 30px; height: 28px; padding: 0 8px; border: 0; border-radius: var(--radius-xs); cursor: pointer;
  background: transparent; color: var(--text); font-size: 13px; font-weight: 700;
}
.image-studio-zoom-btn:hover { background: var(--surface-3); }
.image-studio-zoom-val { min-width: 46px; text-align: center; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.image-studio-save {
  height: 42px; padding: 0 22px; border: 0; border-radius: var(--radius-md); cursor: pointer;
  background: var(--brand-gradient); color: #fff; font-size: 14px; font-weight: 750; box-shadow: var(--brand-glow-strong);
}
.image-studio-save:disabled { opacity: .6; cursor: default; }
/* AI 面板控件：select/textarea/滑杆撑满（数字输入框单独定宽，见下方 field-inline） */
.image-studio .image-studio-aipanel select,
.image-studio .image-studio-aipanel textarea,
.image-studio .image-studio-aipanel input[type="range"] { width: 100%; box-sizing: border-box; }
.image-studio-ai-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 750; color: var(--text); margin-bottom: 12px; }
.image-studio-ai-title svg { width: 18px; height: 18px; color: #2f6db7; }
.image-studio-ai-hint { font-size: 12.5px; color: var(--muted); margin: 4px 0 0; }
.image-studio-field { display: block; margin-bottom: 12px; }
.image-studio-field > span { display: block; font-size: 12px; color: var(--muted); margin-bottom: 5px; }
.image-studio-field > span b { color: var(--text); font-weight: 700; }
.image-studio-aipanel select,
.image-studio-aipanel textarea { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); padding: 7px 9px; font-size: 12.5px; }
.image-studio-expand-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.image-studio-field-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); }
.image-studio .image-studio-aipanel .image-studio-field-inline input { width: 64px; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); padding: 6px 8px; }
.image-studio-field-inline i { font-style: normal; color: var(--muted); }
.image-studio-check { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); margin-bottom: 12px; }
.image-studio-check input { width: auto; }
.image-studio-ai-run { width: 100%; height: 38px; margin-top: 4px; }
/* 选项条内的窄输入（分割行列 / 抠图取色）：单独定宽，避免被全局 input{width:100%} 撑满，且选项条可换行 */
.image-studio-options { flex-wrap: wrap; justify-content: center; }
.image-studio-options .image-studio-field-inline { color: var(--muted); }
.image-studio .image-studio-options .image-studio-field-inline input { width: 56px; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); padding: 5px 7px; }
/* 标注色块唯一正则源(弹窗编辑台+原位编辑坞共用;规格系统已按 [type=color] 根豁免,不需要任何对抗规则):
   34×34 方方正正。**自绘色块**:原生 input[type=color] 的内芯外观各浏览器/各版本自作主张(新版 Chrome 画成
   竖长胶囊,appearance:none+swatch 伪元素都压不住,踩过)——彻底不依赖 UA 渲染:input 透明铺满只负责点击
   弹取色器,颜色显示交给自己的 .image-studio-color-chip(onInput 同步背景色) */
.image-studio-colorwrap {
  position: relative; display: block; width: 34px; height: 34px; padding: 3px; flex: none;
  box-sizing: border-box; border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
}
.image-studio-colorwrap .image-studio-color-chip { display: block; width: 100%; height: 100%; border-radius: 6px; }
.image-studio-colorwrap input.image-studio-color {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; border: 0; opacity: 0; cursor: pointer;
}
.image-studio .image-studio-options .image-studio-field-inline input[type="range"] { width: 110px; }
/* 擦除涂抹层：红色高亮要擦除的区域（叠在工作图上，半透明） */
.image-studio-erase-layer { position: absolute; top: 0; left: 0; pointer-events: auto; cursor: crosshair; opacity: .5; }
/* 标注交互层：覆盖整图捕获指针（画笔/橡皮直接画到工作图，文字点选落字） */
.image-studio-draw-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: auto; }
.image-studio-draw-preview { position: absolute; top: 0; left: 0; pointer-events: none; }
.image-studio .image-studio-options .image-studio-field-inline input[type="text"] { width: 116px; }
/* 换角度：拖拽 orbit 层（覆盖整图） */
.image-studio-angle-drag { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: auto; cursor: grab; }
.image-studio-angle-drag:active { cursor: grabbing; }
/* 分割：网格预览线 */
.image-studio-split-grid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
.image-studio-split-line { position: absolute; background: rgba(47, 109, 183, .9); box-shadow: 0 0 0 calc(1px * var(--studio-inv, 1)) rgba(255, 255, 255, .55); }
.image-studio-split-line.v { top: 0; bottom: 0; width: calc(1.5px * var(--studio-inv, 1)); }
.image-studio-split-line.h { left: 0; right: 0; height: calc(1.5px * var(--studio-inv, 1)); }
/* 扩图：和裁剪一致的观感（框外压暗 + 白色实线框 + 三分线 + 12px 手柄），区别只是向外扩 */
/* 扩图外框醒目化：品牌色虚线 + 白色衬边（原 1px 白线在浅色画布上看不清，用户投诉过） */
.image-studio-expand-frame {
  /* 框体可拖(整框移动=重新分配四边扩展量);手柄各带自己的 resize 光标;线宽随 --studio-inv 屏幕恒定 */
  position: absolute; pointer-events: auto; cursor: move;
  outline: calc(2px * var(--studio-inv, 1)) dashed rgba(79, 99, 221, .95);
  box-shadow: 0 0 0 calc(1px * var(--studio-inv, 1)) rgba(255, 255, 255, .75), inset 0 0 0 calc(1px * var(--studio-inv, 1)) rgba(255, 255, 255, .55);
}
/* 补充带：原图与外框之间「将由 AI 补充」的区域，斜纹高亮标示范围(纹距随 --studio-inv 屏幕恒定) */
.image-studio-expand-band {
  position: absolute; pointer-events: none;
  background: repeating-linear-gradient(45deg, rgba(79, 99, 221, .2) 0 calc(12px * var(--studio-inv, 1)), rgba(79, 99, 221, .06) calc(12px * var(--studio-inv, 1)) calc(24px * var(--studio-inv, 1)));
}
.image-studio-expand-h { position: absolute; width: 13px; height: 13px; background: #4f63dd; border: 2px solid #fff; border-radius: 4px; box-shadow: 0 1px 5px rgba(15, 23, 42, .35); pointer-events: auto; transform: scale(var(--studio-inv, var(--exp-inv, 1))); transform-origin: center; }
.image-studio-expand-h.h-n { left: 50%; top: -6px; margin-left: -6px; cursor: ns-resize; }
.image-studio-expand-h.h-s { left: 50%; bottom: -6px; margin-left: -6px; cursor: ns-resize; }
.image-studio-expand-h.h-w { left: -6px; top: 50%; margin-top: -6px; cursor: ew-resize; }
.image-studio-expand-h.h-e { right: -6px; top: 50%; margin-top: -6px; cursor: ew-resize; }
.image-studio-expand-h.h-nw { left: -6px; top: -6px; cursor: nwse-resize; }
.image-studio-expand-h.h-ne { right: -6px; top: -6px; cursor: nesw-resize; }
.image-studio-expand-h.h-sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.image-studio-expand-h.h-se { right: -6px; bottom: -6px; cursor: nwse-resize; }
/* AI 面板按钮行（重置 + 生成） */
.image-studio-ai-actions { display: flex; gap: 8px; margin-top: 6px; }
.image-studio-ai-actions .image-studio-opt-btn { height: 38px; }
.image-studio-ai-actions .image-studio-ai-run { flex: 1; width: auto; }
@media (max-width: 860px) {
  .image-studio-rail { flex-direction: row; left: 50%; top: auto; bottom: 72px; transform: translateX(-50%); }
  .image-studio-tool { width: 52px; }
  .image-studio-aipanel { left: 12px; right: 12px; width: auto; top: 66px; max-height: 40dvh; }
  .image-studio-options { max-width: calc(100vw - 24px); }
}

/* 工作区：viewport 承载缩放/平移变换，overlay 为工具叠层（画布像素坐标系） */
.image-studio-viewport { position: absolute; top: 0; left: 0; will-change: transform; }
.image-studio-overlay { position: absolute; top: 0; left: 0; pointer-events: none; }
/* 选项条控件：比例 chips + 操作按钮 */
.image-studio-chips { display: inline-flex; gap: 3px; padding: 3px; border-radius: var(--radius-md); background: var(--surface-3); }
.image-studio-chips-wrap { display: flex; flex-wrap: wrap; }
.image-studio-ai-divider { font-size: 11px; color: var(--muted); margin: 10px 0 4px; border-top: 1px solid var(--border); padding-top: 8px; }
/* 换角度：3D 摄像机轨道场景覆盖在工作区上 */
.image-studio-3d { position: absolute; inset: 0; z-index: 6; border-radius: inherit; overflow: hidden; background: radial-gradient(120% 100% at 50% 42%, var(--surface) 0%, var(--surface-3) 72%, var(--bg) 100%); }
/* 自定义光标：深填充+白描边的四向移动标，明暗背景都看得清（OS 默认 grab 在浅色背景上可能发白看不清） */
.image-studio-3d-canvas { display: block; width: 100%; height: 100%; touch-action: none; border-radius: inherit; cursor: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2226%22%20height%3D%2226%22%20viewBox%3D%220%200%2026%2026%22%3E%3Cg%20fill%3D%22%231f2937%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%221.5%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M13%202.5%2015.8%206.8%2010.2%206.8%20Z%22%2F%3E%3Cpath%20d%3D%22M13%2023.5%2010.2%2019.2%2015.8%2019.2%20Z%22%2F%3E%3Cpath%20d%3D%22M2.5%2013%206.8%2010.2%206.8%2015.8%20Z%22%2F%3E%3Cpath%20d%3D%22M23.5%2013%2019.2%2015.8%2019.2%2010.2%20Z%22%2F%3E%3Ccircle%20cx%3D%2213%22%20cy%3D%2213%22%20r%3D%222.4%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") 13 13, grab; }
.image-studio-3d-canvas:active { cursor: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2226%22%20height%3D%2226%22%20viewBox%3D%220%200%2026%2026%22%3E%3Cg%20fill%3D%22%231f2937%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%221.8%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2213%22%20cy%3D%2213%22%20r%3D%225.2%22%2F%3E%3Ccircle%20cx%3D%2213%22%20cy%3D%2213%22%20r%3D%221.8%22%20fill%3D%22%23ffffff%22%20stroke%3D%22none%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") 13 13, grabbing; }
.image-studio-3d-hint { position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-size: 13px; font-weight: 600; letter-spacing: 0.02em; }
.image-studio-shot { font-size: 14px; font-weight: 750; color: var(--text); }
.image-studio-chip { height: 28px; padding: 0 11px; border: 0; border-radius: var(--radius-sm); cursor: pointer; background: transparent; color: var(--muted); font-size: 12.5px; font-weight: 650; }
.image-studio-chip:hover { color: var(--text); }
.image-studio-chip.is-active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-soft); }
.image-studio-ratio-input { flex: none; width: 74px; height: 28px; padding: 0 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font-size: 12px; font-weight: 600; text-align: center; }
.image-studio-ratio-input:focus { outline: none; border-color: var(--accent); }
.image-studio-ratio-input::placeholder { color: var(--muted-2); font-weight: 500; }
.image-studio-opt-sep { width: 1px; height: 22px; background: var(--border); }
.image-studio-opt-btn { height: 30px; padding: 0 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; background: var(--surface); color: var(--text); font-size: 12.5px; font-weight: 650; }
.image-studio-opt-btn:hover { background: var(--surface-3); }
.image-studio-opt-btn.primary { border: 0; background: var(--brand-gradient); color: #fff; box-shadow: var(--brand-glow); }
/* 裁剪框：框外压暗 + 三分线 + 8 手柄（手柄按缩放反向补偿，保持屏上大小稳定） */
/* 框外压暗层：普通 div + clip-path 挖洞（替代巨型 box-shadow，缩放不卡顿）；裁剪/扩图共用 */
.image-studio-dim { position: absolute; background: rgba(15, 23, 42, .46); pointer-events: none; }
/* 框线=品牌蓝主线+白衬边双线(纯白线压白图隐形,用户报修;双线在任何底色上都读得清,与手柄同色系) */
/* 线宽一律乘 var(--studio-inv):overlay 在 viewport scale 空间里,固定 px 会被放大——
   秒开预览(低分辨率工作图)scale>1 时裁剪框/三分线粗好几倍,高清接管才恢复(用户报修)。
   --studio-inv 由 imageStudioApplyView 收口写在 overlay 上,屏幕视觉恒定。 */
.image-studio-crop {
  position: absolute;
  pointer-events: auto;
  cursor: move;
  outline: calc(2px * var(--studio-inv, 1)) solid rgba(47, 109, 183, .95);
  outline-offset: calc(-1px * var(--studio-inv, 1));
  box-shadow: 0 0 0 calc(1px * var(--studio-inv, 1)) rgba(255, 255, 255, .85), inset 0 0 0 calc(1px * var(--studio-inv, 1)) rgba(255, 255, 255, .85);
}
.image-studio-crop-thirds {
  position: absolute; inset: 0; pointer-events: none; opacity: .6;
  background-image: linear-gradient(rgba(47, 109, 183, .45) calc(1px * var(--studio-inv, 1)), transparent calc(1px * var(--studio-inv, 1))), linear-gradient(90deg, rgba(47, 109, 183, .45) calc(1px * var(--studio-inv, 1)), transparent calc(1px * var(--studio-inv, 1)));
  background-size: 33.33% 33.33%;
}
.image-studio-crop-h { position: absolute; width: 12px; height: 12px; background: #fff; border: 1.5px solid #2f6db7; border-radius: 3px; pointer-events: auto; transform: scale(var(--studio-inv, var(--crop-inv, 1))); transform-origin: center; }
.image-studio-crop-h.h-nw { left: -6px; top: -6px; cursor: nwse-resize; }
.image-studio-crop-h.h-n { left: 50%; top: -6px; margin-left: -6px; cursor: ns-resize; }
.image-studio-crop-h.h-ne { right: -6px; top: -6px; cursor: nesw-resize; }
.image-studio-crop-h.h-e { right: -6px; top: 50%; margin-top: -6px; cursor: ew-resize; }
.image-studio-crop-h.h-se { right: -6px; bottom: -6px; cursor: nwse-resize; }
.image-studio-crop-h.h-s { left: 50%; bottom: -6px; margin-left: -6px; cursor: ns-resize; }
.image-studio-crop-h.h-sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.image-studio-crop-h.h-w { left: -6px; top: 50%; margin-top: -6px; cursor: ew-resize; }
/* 旋转标:裁剪框底中下方的圆形手柄(拖动=旋转整幅图,45° 吸附,松手烘焙);尺寸/间距随 --crop-inv 保持屏幕恒定。
   放底部而非顶部:顶部上方是浮动标题带(pointer-events:auto),放上面会被标题手势截走。 */
.image-studio-crop-rot {
  position: absolute;
  left: 50%;
  bottom: calc(-32px * var(--studio-inv, var(--crop-inv, 1)));
  width: 18px;
  height: 18px;
  margin-left: -9px;
  display: grid;
  place-items: center;
  background: #fff;
  border: 1.5px solid #2f6db7;
  border-radius: 50%;
  color: #2f6db7;
  font-size: 11px;
  line-height: 1;
  cursor: grab;
  pointer-events: auto;
  transform: scale(var(--studio-inv, var(--crop-inv, 1)));
  transform-origin: center;
  user-select: none;
  -webkit-user-select: none;
}
.image-studio-crop-rot:active { cursor: grabbing; }
.image-studio-crop-rot::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 1.5px;
  height: 12px;
  background: rgba(255, 255, 255, .92);
}
.image-studio-crop-rot-badge {
  position: absolute;
  left: 50%;
  bottom: calc(-60px * var(--studio-inv, var(--crop-inv, 1)));
  transform: translateX(-50%) scale(var(--studio-inv, var(--crop-inv, 1)));
  transform-origin: center;
  padding: 2px 8px;
  border-radius: 8px;
  background: rgba(15, 23, 42, .78);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  pointer-events: none;
}
.image-studio-crop-rot-badge[hidden] { display: none; }

/* ============ 画布原位编辑（双击媒体：镜头聚焦 + 编辑面贴卡 + 底部工具坞） ============ */
/* 层级：stage 内 links(1) < content(2) < selection(5) < inline-panel(36) < 本层(60) < HUD(86)。
   根层不吃事件；罩层挡住其它卡片、拖动=平移画布；surface 每帧由 JS 贴合媒体屏幕矩形。 */
.canvas-edit-layer { position: absolute; inset: 0; z-index: 60; pointer-events: none; }
/* 单路径压暗层：even-odd 洞直露家族卡真实 DOM，每帧工作量只与家族数量有关。 */
.canvas-edit-dim { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.canvas-edit-dim path { fill: rgba(241, 244, 249, .66); }
body.theme-dark .canvas-edit-dim path { fill: rgba(5, 8, 15, .68); }
/* 透明交互层：拖动=平移、双击空白=退出、滚轮冒泡缩放。 */
.canvas-edit-veil { position: absolute; inset: 0; pointer-events: auto; cursor: grab; background: transparent; }
.canvas-edit-veil:active { cursor: grabbing; }
/* 家族卡上方的透明点击垫：点击=对焦过去切换编辑，顺便挡住底下卡片的选中/拖拽误操作 */
.canvas-edit-family-hits { position: absolute; inset: 0; pointer-events: none; }
.canvas-edit-family-hit {
  position: absolute; left: 0; top: 0; pointer-events: auto; cursor: pointer; border-radius: 12px;
  background-position: center; background-repeat: no-repeat; background-size: cover;
  box-shadow: 0 7px 20px rgba(15, 23, 42, .16);
}
.canvas-edit-family-hit:hover { box-shadow: inset 0 0 0 2px rgba(79, 99, 221, .7); }
/* 裁剪/扩图的框外压暗：只盖工作图自身（图外没有罩染色，铺出去会显灰色矩形/洗灰全亮的分支卡） */
/* 亮色遮罩必须也是深色纱:奶白半透明(rgba(228,232,238,.5))盖上去=一层雾,框外内容白蒙蒙看不清(用户报修);
   暗色本来就好。裁剪/旋转共用这同一个遮罩=两处效果天然一致 */
.canvas-edit-surface .image-studio-dim { background: rgba(15, 23, 42, .38); }
body.theme-dark .canvas-edit-surface .image-studio-dim { background: rgba(9, 12, 19, .48); }
/* 左上角状态签：当前工具 · 素材名 */
/* 编辑态标题=画布卡头同款(徽章+蓝字缩略);可交互:拖动移卡/双击删除(手势在 bindCanvasEditCaptionGestures) */
.canvas-edit-caption {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 420px;
  padding: 0 2px;
  color: var(--card-accent, #2f6db7);
  font-size: 13px;
  font-weight: 900;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: auto;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.canvas-edit-caption:active { cursor: grabbing; }
.canvas-edit-caption strong { overflow: hidden; text-overflow: ellipsis; font-weight: 900; }
.canvas-edit-caption .infinite-card-badge {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--card-accent, #2f6db7);
  font-size: 10px;
}

.canvas-edit-caption[hidden] { display: none; }
.canvas-edit-surface {
  position: absolute; left: 0; top: 0; pointer-events: auto; will-change: transform; transform-origin: 0 0;
  touch-action: none; /* 触屏画笔/裁剪手柄不被浏览器手势抢走 */
  border-radius: var(--canvas-edit-surface-radius, 8px);
  backface-visibility: hidden;
  contain: layout style;
}
/* 棋盘底/阴影只在有媒体内容(入场预览或已画像素)后出现——内容就绪前 surface 揭开的空窗帧
   曾裸露棋盘格「闪一下」;类由 canvasEditSurfaceMarkContent 收口挂上,finalize 清。
   不描边:图片边上只留当前工具自己的框(裁剪框等),避免「外面套两个框」;
   静态棋盘底:透明像素(抠图结果)可辨识;亮色主题浅棋盘、暗色深棋盘 */
.canvas-edit-surface.has-media-content {
  box-shadow: 0 8px 26px rgba(15, 23, 42, .18);
  border-radius: var(--canvas-edit-surface-radius, 8px);
  background:
    conic-gradient(rgba(148, 163, 184, .3) 0 25%, transparent 0 50%, rgba(148, 163, 184, .3) 0 75%, transparent 0) 0 0 / 20px 20px,
    #fdfdfe;
}
body.theme-dark .canvas-edit-surface.has-media-content {
  box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
  background:
    conic-gradient(rgba(148, 163, 184, .13) 0 25%, transparent 0 50%, rgba(148, 163, 184, .13) 0 75%, transparent 0) 0 0 / 20px 20px,
    #10141d;
}
/* 裁剪旋转预览态:图斜着转出了 surface 的轴对齐矩形,棋盘格/阴影钉在原方位不跟转=两层错位;
   旋转期间隐藏 surface 自己的底纹与阴影,明暗主题都要压住 */
.canvas-edit-surface.is-crop-rotating,
body.theme-dark .canvas-edit-surface.is-crop-rotating {
  background: none;
  box-shadow: none;
}
/* 阴影改挂在随图旋转的工作 canvas 上=阴影一直在且永远贴着图转(用户:白图没阴影看不清边界)。
   性能:transform 旋转不触发重绘,阴影已烙在该图层光栅里、每帧只是合成——零逐帧绘制开销 */
.canvas-edit-surface canvas.is-rot-preview { box-shadow: 0 8px 26px rgba(15, 23, 42, .22); }
body.theme-dark .canvas-edit-surface canvas.is-rot-preview { box-shadow: 0 10px 30px rgba(0, 0, 0, .45); }
/* 图片模式：viewport 只做 scale(编辑面宽/工作图像素宽)，工具叠层(裁剪框/涂抹/扩图手柄)可越出 surface */
.canvas-edit-surface .image-studio-viewport { overflow: visible; }
.canvas-edit-surface .image-studio-canvas { box-shadow: none; }
.canvas-edit-surface .image-studio-overlay { overflow: visible; }
.canvas-edit-entry-preview { display: block; width: 100%; height: 100%; object-fit: fill; user-select: none; pointer-events: none; }
.canvas-edit-bitmap-preview { position: absolute; inset: 0; z-index: 0; }
.canvas-edit-surface .image-studio-canvas { z-index: 1; }
.canvas-edit-surface .image-studio-overlay { z-index: 2; }
.canvas-edit-loading {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 5;
  background: rgba(10, 14, 24, .55); color: #e6ebf5; font-size: 13px; font-weight: 650; border-radius: 4px;
}
.canvas-edit-loading[hidden] { display: none; }
/* 有秒开预览时的悬浮模式:不罩预览,只在底部浮一颗进度药丸(与任务详情高清指示器同位感) */
.canvas-edit-loading.is-overlay {
  background: transparent;
  place-items: end center;
  padding-bottom: 18px;
  pointer-events: none;
}
.canvas-edit-loading.is-hd-loading.is-overlay {
  inset: auto 0 -38px 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 0;
}
/* 高清加载进度药丸(与任务详情高清指示器同观感;项目禁 backdrop-filter,用实底):
   is-progress 前=扫动不确定态,拿到 content-length 后=确定宽度 --hd-progress */
.canvas-edit-hd-pill {
  display: flex; align-items: center; gap: 9px; padding: 7px 14px; border-radius: 999px;
  background: rgba(15, 23, 42, .78); color: #fff; font-size: 12px; line-height: 1; white-space: nowrap;
  box-shadow: 0 4px 14px rgba(15, 23, 42, .28);
}
.canvas-edit-hd-bar {
  position: relative; width: 72px; height: 3px; border-radius: 2px;
  background: rgba(255, 255, 255, .28); overflow: hidden; flex: 0 0 auto;
}
.canvas-edit-hd-bar::after {
  content: ""; position: absolute; top: 0; left: 0; bottom: 0; width: 40%; border-radius: 2px;
  background: #fff; animation: canvasEditHdSlide 1.1s ease-in-out infinite;
}
.canvas-edit-loading.is-progress .canvas-edit-hd-bar::after {
  animation: none; width: var(--hd-progress, 0%); transition: width .18s ease;
}
@keyframes canvasEditHdSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(260%); } }
.canvas-edit-layer.canvas-edit-exiting :is(.canvas-edit-dock, .canvas-edit-side, .canvas-edit-caption, .canvas-edit-family-hits) {
  visibility: hidden !important; pointer-events: none !important;
}
.canvas-edit-layer.canvas-edit-exiting :is(.canvas-edit-surface, .canvas-edit-veil) { pointer-events: none !important; }
/* 空格抓手:编辑态所有工具层上统一显示抓手(实际平移由编辑层捕获阶段接管) */
#canvasEditLayer.space-pan, #canvasEditLayer.space-pan * { cursor: grab !important; }
#canvasEditLayer.space-pan:active, #canvasEditLayer.space-pan *:active { cursor: grabbing !important; }
/* ── 底部工具坞：画布底部居中浮动，选项条(随工具变) + 工具/动作行（毛玻璃浮层，单行不换行） ── */
.canvas-edit-dock {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  max-width: min(96%, 1120px); pointer-events: none;
  animation: canvasEditDockIn .2s ease;
}
@keyframes canvasEditDockIn { from { opacity: 0; transform: translateX(-50%) translateY(10px); } }
.canvas-edit-dock > * { pointer-events: auto; }
/* 实底面板：本项目全局禁用 backdrop-filter(性能规则)，半透明底没有模糊=一片奶白糊；直接实底最干净也最快 */
.canvas-edit-options,
.canvas-edit-toolrow {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 20px 48px rgba(8, 12, 22, .2), 0 2px 10px rgba(8, 12, 22, .08);
}
.canvas-edit-options {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 7px 16px;
  border-radius: 16px; color: var(--text); max-width: 100%; flex-wrap: wrap; justify-content: center;
}
.canvas-edit-options:empty { display: none; }
/* 选项条里的表单控件必须紧凑：全局 input{width:100%} 会把滑杆撑成整行大板（标注工具踩过）。
   色块样式唯一正则源是 input.image-studio-color(全端全容器一条规则,见 image-studio 段),这里不再重复。 */
.canvas-edit-options input[type="range"] { width: 150px; flex: none; }
.canvas-edit-options .image-studio-field-inline input[type="text"] { width: 150px; flex: none; height: 30px; }
.canvas-edit-options .image-studio-field-inline { flex: none; white-space: nowrap; }
.canvas-edit-toolrow {
  display: flex; align-items: center; gap: 4px; padding: 8px 12px;
  border-radius: 18px; max-width: 100%;
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
}
.canvas-edit-toolrow::-webkit-scrollbar { display: none; }
.canvas-edit-tools { display: flex; align-items: center; gap: 3px; flex: none; }
.canvas-edit-dock .image-studio-tool { width: 50px; padding: 6px 2px; border-radius: 12px; flex: none; transition: background .15s ease, color .15s ease, transform .15s ease; }
.canvas-edit-dock .image-studio-tool:hover { transform: translateY(-1px); }
.canvas-edit-dock .image-studio-tool-ico svg { width: 18px; height: 18px; }
.canvas-edit-dock .image-studio-tool-label { font-size: 10.5px; }
.canvas-edit-sep {
  flex: none; width: 1px; height: 26px; margin: 0 6px;
  background: linear-gradient(180deg, transparent, var(--border) 28%, var(--border) 72%, transparent);
}
.canvas-edit-actbtn {
  flex: none; height: 33px; padding: 0 13px; border: 1px solid var(--border); border-radius: 11px;
  background: var(--surface); color: var(--text); font-size: 12.5px; font-weight: 700; cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease, transform .14s ease, box-shadow .14s ease;
  white-space: nowrap;
}
.canvas-edit-actbtn:hover:not(:disabled) { background: var(--surface-3); transform: translateY(-1px); }
.canvas-edit-actbtn.primary { border: 0; background: var(--brand-gradient); color: #fff; box-shadow: var(--brand-glow); }
.canvas-edit-actbtn.primary:hover:not(:disabled) { box-shadow: var(--brand-glow), 0 6px 18px rgba(79, 99, 221, .35); }
.canvas-edit-actbtn:disabled { opacity: .55; cursor: default; }
.canvas-edit-exit:hover:not(:disabled) { background: var(--danger-soft); color: #d92d20; }
/* AI 面板：停靠画布右侧（镜头会为它让位），不再盖住正在编辑的图 */
.canvas-edit-side {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 296px; display: flex; pointer-events: none;
}
.canvas-edit-side .image-studio-aipanel {
  position: static; width: 100%; max-height: min(66dvh, 560px); overflow: auto; pointer-events: auto;
  padding: 12px 13px; border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 18px 44px rgba(8, 12, 22, .18), 0 2px 8px rgba(8, 12, 22, .08);
  overscroll-behavior: contain;
}
/* ── 视频模式 ── */
.canvas-edit-surface .canvas-video-frame {
  position: absolute; inset: 0; display: block; max-width: none; max-height: none; border-radius: 4px;
}
.canvas-edit-surface .canvas-video-frame video {
  display: block; width: 100%; height: 100%; max-width: none; max-height: none;
  object-fit: contain; background: transparent;
}
.canvas-video-transport {
  display: grid; grid-template-columns: auto minmax(220px, 1fr) auto; align-items: center;
  gap: 8px 14px; width: min(92vw, 680px); flex-wrap: nowrap;
}
.canvas-video-transport .canvas-video-timeline { width: 100%; padding: 2px 6px 0; }
/* 播放头：全片定位指针（与截段选区同轨一条时间轴），可拖 */
.canvas-video-playhead {
  position: absolute; top: 50%; z-index: 2;
  width: 4px; min-width: 4px; height: 30px; min-height: 30px; padding: 0; border: 0; border-radius: 999px;
  transform: translate(-50%, -50%);
  background: #0f172a; box-shadow: 0 0 0 1.5px #fff, 0 2px 8px rgba(15, 23, 42, .35);
  cursor: ew-resize;
}
body.theme-dark .canvas-video-playhead { background: #e6ebf5; box-shadow: 0 0 0 1.5px rgba(18, 21, 29, .9), 0 2px 8px rgba(0, 0, 0, .4); }
.canvas-video-params { row-gap: 8px; }
.canvas-video-param {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 650; color: var(--muted); white-space: nowrap;
}
.canvas-video-param select, .canvas-video-param input[type="number"] { width: auto; min-width: 0; height: 30px; padding: 0 8px; font-size: 12.5px; }
.canvas-video-param input[type="number"] { width: 68px; }
.canvas-video-param input[type="checkbox"] { width: auto; margin: 0 2px 0 0; }
.canvas-video-speed-hint { margin: 0; padding: 0 6px; font-size: 12px; text-align: center; background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 4px 12px; box-shadow: var(--shadow-popover); }
.canvas-video-speed-hint[hidden] { display: none; }
/* 播放/片段预览时弱化裁剪框（原样式挂在旧弹窗类上，这里按层根 id 重挂） */
#canvasEditLayer.clip-previewing .canvas-video-crop-overlay { opacity: .42; }
#canvasEditLayer.clip-previewing .canvas-video-crop-box { pointer-events: none; }
#canvasEditLayer.video-playing .canvas-video-crop-box,
#canvasEditLayer.clip-previewing .canvas-video-crop-box { background: rgba(47, 109, 183, .04); box-shadow: 0 0 0 1px rgba(15, 23, 42, .18); }
#canvasEditLayer.video-playing .canvas-video-crop-box span,
#canvasEditLayer.clip-previewing .canvas-video-crop-box span { opacity: .72; }
/* 只在浮钮本身切 class；避免给 body 换 class 导致整个应用子树重算样式。 */
#globalGenFab.canvas-edit-hidden { display: none !important; }
/* 编辑期隐藏画布角落 HUD（z86 高于编辑层，会盖住/拦截工具坞；画布撤回此时也不该用）。基础规则带 #appLayout，特异性要压过 */
body:not(.auth-required) #appLayout .infinite-canvas-stage.canvas-editing .canvas-corner-hud {
  opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .16s ease, visibility .16s ease;
}
/* 选项条:比例 chips + 自定义输入放独立横滚区,右侧按钮(重置/应用裁剪)常驻不滚 */
.image-studio-opt-scroll {
  display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.image-studio-opt-scroll::-webkit-scrollbar { display: none; }
.image-studio-opt-scroll .image-studio-chips { flex: none; flex-wrap: nowrap; }
/* 工具坞动作区(撤回/重做/保存/退出):不参与工具横滚,始终可见 */
.canvas-edit-actions { display: flex; align-items: center; gap: 6px; flex: none; }

/* 手机端：坞贴底全宽、工具区横向滚动(动作区常驻)、画布角落 HUD 让位 */
@media (max-width: 820px) {
  .canvas-edit-dock { left: 8px; right: 8px; bottom: 10px; transform: none; max-width: none; }
  .canvas-edit-options { padding: 6px 10px; gap: 8px; flex-wrap: nowrap; justify-content: flex-start; }
  .canvas-edit-toolrow { flex-wrap: nowrap; max-width: 100%; }
  .canvas-edit-toolrow .canvas-edit-tools { flex: 1; min-width: 0; overflow-x: auto; -webkit-overflow-scrolling: touch; flex-wrap: nowrap; scrollbar-width: none; }
  .canvas-edit-toolrow .canvas-edit-tools::-webkit-scrollbar { display: none; }
  .canvas-edit-dock .image-studio-tool { width: 48px; flex: none; }
  .canvas-edit-actbtn { flex: none; }
  .canvas-video-transport { width: 100%; }
  /* 手机端没有右侧空间：AI 面板改为坞上方的抽屉(收窄贴左,不占整屏宽) */
  .canvas-edit-side { left: 8px; right: auto; width: min(320px, calc(100vw - 16px)); top: auto; bottom: 172px; transform: none; }
  .canvas-edit-side .image-studio-aipanel { max-height: 42dvh; }
  /* 图片编辑坞:手机端不放退出按钮(省空间;退出=双击空白/系统返回) */
  .canvas-edit-actions [data-studio-close] { display: none; }
  /* 手机端扩图不放提示词输入(把面板顶得很高;需要补充提示词去桌面端) */
  .canvas-edit-side .image-studio-prompt-field { display: none; }
  /* 视频参数行:横滚 + 保存/退出常驻布局与图片坞一致 */
  .canvas-video-params { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; justify-content: flex-start; }
  .canvas-video-params::-webkit-scrollbar { display: none; }
  .canvas-video-params .canvas-edit-actbtn, .canvas-video-params .image-studio-iconbtn { flex: none; }
}
/* 画布视频卡：单行紧凑 transport。模块固定尺寸后控件不再为右下角缩放手柄让位。 */
.infinite-card.media-card {
  --media-transport-edge-inset: 6px;
}

.infinite-card-video-controls {
  --vc-bg: rgba(255, 255, 255, 0.78);
  --vc-border: rgba(15, 23, 42, 0.08);
  --vc-text: #475467;
  --vc-accent: #2f6db7;
  --vc-accent-strong: #255a9c;
  --vc-button-hover: rgba(47, 109, 183, 0.11);
  --vc-track: rgba(100, 116, 139, 0.2);
  --vc-buffered: rgba(71, 85, 105, 0.38);
  --vc-thumb-ring: #ffffff;
  --vc-shadow: 0 2px 7px rgba(15, 23, 42, 0.09);
  --vc-edge-inset: var(--media-transport-edge-inset, 6px);
  position: absolute;
  inset-inline: var(--vc-edge-inset);
  bottom: 6px;
  z-index: 4;
  min-width: 0;
  min-height: 28px;
  display: grid;
  grid-template-columns: 24px minmax(42px, 1fr) auto;
  align-items: center;
  gap: 5px;
  padding: 1px 5px;
  border: 1px solid var(--vc-border);
  border-radius: 7px;
  background: var(--vc-bg);
  color: var(--vc-text);
  box-shadow: var(--vc-shadow);
}

body.theme-dark .infinite-card-video-controls {
  --vc-bg: rgba(12, 15, 22, 0.8);
  --vc-border: rgba(255, 255, 255, 0.1);
  --vc-text: #b4c1d2;
  --vc-accent: #78b3e8;
  --vc-accent-strong: #9cc8ee;
  --vc-button-hover: rgba(120, 179, 232, 0.14);
  --vc-track: rgba(180, 193, 210, 0.2);
  --vc-buffered: rgba(180, 193, 210, 0.4);
  --vc-thumb-ring: #121821;
  --vc-shadow: 0 2px 8px rgba(0, 0, 0, 0.22);
}

.infinite-card-video-controls .infinite-card-video-toggle {
  width: 24px;
  min-width: 24px;
  max-width: 24px;
  height: 24px;
  min-height: 24px;
  max-height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  display: inline-grid;
  place-items: center;
  background: transparent;
  color: var(--vc-accent);
  cursor: pointer;
  box-shadow: none;
  transition: color 120ms ease, background-color 120ms ease;
}

.infinite-card-video-controls .infinite-card-video-toggle:hover {
  background: var(--vc-button-hover);
  color: var(--vc-accent-strong);
}

.infinite-card-video-controls .infinite-card-video-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--vc-accent) 26%, transparent);
}

.infinite-card-video-toggle .ui-icon {
  display: inline-grid;
  place-items: center;
  pointer-events: none;
}

.infinite-card-video-toggle .ui-icon svg {
  width: 12px;
  height: 12px;
  min-width: 12px;
  min-height: 12px;
}

.infinite-card-video-controls input[type="range"] {
  --video-progress: 0%;
  --video-buffered: 0%;
  width: 100%;
  min-width: 0;
  min-height: 0 !important;
  max-height: 20px !important;
  height: 20px;
  margin: 0;
  padding: 0 !important;
  border: 0 !important;
  appearance: none;
  background: transparent !important;
  box-shadow: none !important;
  cursor: pointer;
}

.infinite-card-video-controls input[type="range"]::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--vc-accent) 0 var(--video-progress), var(--vc-buffered) var(--video-progress) var(--video-buffered), var(--vc-track) var(--video-buffered) 100%);
}

.infinite-card-video-controls input[type="range"]::-webkit-slider-thumb {
  width: 10px;
  height: 10px;
  margin-top: -3.5px;
  appearance: none;
  border: 1.5px solid var(--vc-thumb-ring);
  border-radius: 50%;
  background: var(--vc-accent);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.22);
}

.infinite-card-video-controls input[type="range"]::-moz-range-track { height: 3px; border-radius: 999px; background: var(--vc-track); }
.infinite-card-video-controls input[type="range"]::-moz-range-progress { height: 3px; border-radius: 999px; background: var(--vc-accent); }
.infinite-card-video-controls input[type="range"]::-moz-range-thumb { width: 8px; height: 8px; border: 1.5px solid var(--vc-thumb-ring); border-radius: 50%; background: var(--vc-accent); }
.infinite-card-video-controls input[type="range"]:focus-visible { outline: 2px solid var(--vc-accent); outline-offset: 1px; border-radius: 999px; }
.infinite-card-video-controls input[type="range"]:disabled { opacity: 0.45; cursor: default; }

.infinite-card-video-controls [data-canvas-video-timecode] {
  color: currentColor;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  text-align: right;
  white-space: nowrap;
}

.infinite-card.media-card [data-canvas-media-drag] { container-type: inline-size; }

@container (max-width: 200px) {
  .infinite-card-video-controls {
    grid-template-columns: 24px minmax(42px, 1fr);
  }
  .infinite-card-video-controls [data-canvas-video-timecode] { display: none; }
}

/* ============ 导演台 独立工作台（全宽全屏 modal，三栏专业布局） ============ */
.poser-studio-mask { padding: 0; }
.poser-studio-panel {
  --poser-accent: #7c3aed;
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  border-radius: 0;
  overflow: hidden;
  overscroll-behavior: none; /* 全屏导演台里手势不外溢到浏览器(防误触发前进/后退/关标签页) */
}
.poser-studio { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; height: 100%; background: var(--surface, #fff); overflow: hidden; color: var(--text); }
/* ── 顶栏 ── */
.poser-studio-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 5px 16px; border-bottom: 1px solid var(--border); background: linear-gradient(180deg, #faf9ff, #ffffff); }
.poser-studio-brand { display: flex; align-items: center; gap: 9px; min-width: 0; }
.poser-studio-badge { display: inline-grid; place-items: center; width: 32px; height: 26px; border-radius: 8px; background: var(--brand-gradient, linear-gradient(135deg, #7c3aed, #4f63dd)); color: #fff; font-size: 11px; font-weight: 800; letter-spacing: .5px; box-shadow: 0 3px 9px rgba(124, 58, 237, .26); }
.poser-studio-brandtext { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.poser-studio-brandtext strong { font-size: 14px; font-weight: 850; color: #101828; }
.poser-studio-brandtext span { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.poser-studio-modes { display: inline-flex; gap: 3px; padding: 3px; border-radius: 12px; background: var(--surface-3, #f1f5f9); border: 1px solid var(--border); }
.poser-studio-modes .poser-mode { display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; border-radius: 8px; padding: 4px 12px; color: #475569; font-weight: 750; font-size: 12.5px; cursor: pointer; transition: background .14s ease, color .14s ease; }
.poser-mode-ico { display: inline-flex; }
.poser-mode-ico svg { width: 17px; height: 17px; display: block; }
.poser-studio-modes .poser-mode:hover { color: var(--poser-accent); background: rgba(124, 58, 237, .08); }
.poser-studio-modes .poser-mode.active { background: var(--poser-accent); color: #fff; box-shadow: 0 3px 10px rgba(124, 58, 237, .38); }
.poser-mode-key { display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 4px; background: rgba(15,23,42,.1); color: inherit; font-size: 10px; font-weight: 800; line-height: 1; opacity: .7; }
.poser-studio-modes .poser-mode.active .poser-mode-key { background: rgba(255,255,255,.25); opacity: .95; }
.poser-studio-bar-right { display: flex; align-items: center; gap: 7px; }
.poser-reverse-btn { display: inline-flex; align-items: center; gap: 6px; }
.poser-reverse-icon { display: inline-flex; }
.poser-reverse-icon svg { width: 16px; height: 16px; display: block; }
.poser-bar-sep { width: 1px; height: 22px; background: var(--border); margin: 0 2px; }
.poser-iconbtn { width: 30px; height: 30px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 8px; background: #fff; color: #475569; cursor: pointer; transition: border-color .14s ease, color .14s ease, background .14s ease; }
.poser-iconbtn svg { width: 17px; height: 17px; }
.poser-iconbtn:hover { border-color: var(--poser-accent); color: var(--poser-accent); background: #f7f4fe; }
.poser-iconbtn-close:hover { border-color: var(--danger); color: var(--danger); background: var(--danger-soft, #fff3f1); }
.poser-ghost-btn { border: 1px solid var(--border); border-radius: 8px; background: #fff; color: #475569; font-size: 12.5px; font-weight: 700; padding: 5px 11px; cursor: pointer; transition: border-color .14s ease, color .14s ease; }
.poser-ghost-btn:hover { border-color: var(--poser-accent); color: var(--poser-accent); }
/* ── 三栏主体 ── */
.poser-studio-main { display: grid; grid-template-columns: 268px minmax(0, 1fr) 330px; min-height: 0; }
.poser-studio-left, .poser-studio-right { display: flex; flex-direction: column; gap: 10px; padding: 16px; overflow: auto; background: var(--surface-2, #f8fafc); }
.poser-studio-left { border-right: 1px solid var(--border); }
.poser-studio-right { border-left: 1px solid var(--border); }
.poser-studio-left .poser-actor-list { max-height: none; flex: 1 1 auto; }
/* 机位多了不无限往下顶：列表本身限高、内部滚动（含自由视角行约 4 行后出现滚动条） */
.poser-studio-left .poser-shot-list { max-height: 184px; overflow: auto; flex: 0 0 auto; }
/* 全站缩放系统(styles.part3.css)用 :where(button){height:var(--scale*)!important} 把"所有按钮"强制成大触控高度,
   会把列表行里的 ✕/⧉ 小图标按钮撑到 33px → 整行被撑高。导演台不该参与缩放:用 #poserStudioModal 的 ID 特异度
   (1,0,0 高于那些 :where 规则的 0,N,1)一次性压过所有缩放规则,把列表小图标按钮尺寸还原,行高即回落。 */
#poserStudioModal :where(.poser-actor-dup, .poser-actor-del, .poser-shot-del) { width: 24px !important; height: 24px !important; min-height: 0 !important; padding: 0 !important; }
.poser-studio-tabs { display: none; } /* 手机端抽屉标签(responsive.css 里 mobile-ui 才显示);桌面不参与布局 */
.poser-studio-sec { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 11.5px; font-weight: 750; letter-spacing: .5px; color: #66738a; }
.poser-studio-sec > span { display: inline-flex; align-items: center; gap: 7px; }
.poser-studio-sec > span::before { content: ""; width: 3px; height: 12px; border-radius: 2px; background: var(--poser-accent, #7c3aed); opacity: .8; }
.poser-studio-sec:not(:first-child) { margin-top: 9px; padding-top: 14px; border-top: 1px solid var(--border); }
/* 右栏内容分组卡片化:角色属性 / 场景·灯光·机位·环境 各自一张浅色卡,层级一眼可分(原来平铺一串裸控件) */
.poser-studio-right .poser-inspector,
.poser-studio-right .poser-scene {
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface, #fff);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.poser-studio-right .poser-inspector:empty { display: none; padding: 0; border: 0; }
/* 右栏控件统一节奏:下拉/数值框同高同圆角,不再一格大一格小 */
.poser-studio-right select,
.poser-studio-right input[type="number"] {
  min-height: 32px;
  border-radius: 9px;
  box-sizing: border-box;
}
body.theme-dark .poser-studio-right .poser-inspector,
body.theme-dark .poser-studio-right .poser-scene {
  background: rgba(18, 21, 28, 0.55);
  border-color: rgba(83, 90, 104, 0.5);
  box-shadow: none;
}
.poser-studio-count { display: inline-grid; place-items: center; min-width: 20px; height: 18px; padding: 0 6px; border-radius: 999px; background: var(--accent-2-soft, #ecebfd); color: var(--accent-2-strong, #574bd4); font-size: 11px; font-weight: 800; }
.poser-add-group { display: grid; gap: 7px; }
.poser-add-shapes { align-items: center; }
.poser-tool-accent { border-color: var(--poser-accent); color: var(--poser-accent); background: rgba(124, 58, 237, .07); font-weight: 750; }
.poser-tool-accent:hover:not(:disabled) { background: var(--poser-accent); color: #fff; border-color: var(--poser-accent); }
.poser-field-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.poser-hdr-row { display: flex; gap: 6px; }
.poser-hdr-pick { flex: 1 1 auto; }
/* ── 中央视口 ── */
.poser-studio-stage { position: relative; min-height: 0; overflow: hidden; background: radial-gradient(120% 100% at 50% 0%, #f2f5fb 0%, #e7ecf4 100%); touch-action: none; overscroll-behavior: none; }
/* canvas 用绝对定位锁死在预览框内（stage 已是 relative），保证它正好=可见预览框，
   不会把下面/外面的 UI 也算进尺寸导致 3D 画面被放大/裁切 */
.poser-studio-stage .poser-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.poser-studio-stage::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 90px rgba(15, 23, 42, .12); }
/* ── 底栏 ── */
.poser-studio-foot { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px; padding: 5px 16px; border-top: 1px solid var(--border); background: #fff; }
.poser-studio-foot-left { display: flex; align-items: center; gap: 14px; min-width: 0; justify-self: start; }
.poser-frame { justify-self: center; }
.poser-studio-foot-actions { justify-self: end; }
.poser-studio-foot-hint { font-size: 12px; color: var(--muted); }
.poser-capture-thumb { display: flex; align-items: center; gap: 8px; padding: 3px 9px 3px 3px; border: 1px solid var(--ok-soft, #cdeee2); border-radius: 10px; background: var(--ok-soft, #e9f6f1); }
.poser-capture-thumb img { width: 34px; height: 34px; object-fit: cover; border-radius: 8px; border: 1px solid rgba(0,0,0,.08); display: block; }
.poser-capture-thumb span { font-size: 12px; font-weight: 750; color: var(--ok, #13795b); white-space: nowrap; }
/* 画幅比例：底栏按钮 + 画布取景遮罩 */
.poser-frame { display: inline-flex; align-items: center; gap: 8px; }
.poser-frame-label { font-size: 12px; font-weight: 750; color: #475569; }
.poser-frame-btns { display: inline-flex; gap: 4px; }
.poser-frame-btn { border: 1px solid var(--border); background: #fff; color: #475569; font-size: 12px; font-weight: 700; padding: 4px 9px; border-radius: 8px; cursor: pointer; transition: border-color .12s, color .12s, background .12s; }
.poser-frame-btn:hover { border-color: var(--poser-accent, #7c3aed); color: var(--poser-accent, #7c3aed); }
.poser-frame-btn.active { background: var(--poser-accent, #7c3aed); color: #fff; border-color: var(--poser-accent, #7c3aed); }
.poser-frame-mask { position: absolute; pointer-events: none; box-shadow: 0 0 0 9999px rgba(15, 23, 42, .42); border: 1px solid rgba(255, 255, 255, .85); border-radius: 1px; z-index: 3; }
.poser-studio-foot-actions { display: flex; gap: 10px; }
.poser-studio-foot-actions .secondary, .poser-studio-foot-actions .primary { padding: 6px 18px; border-radius: 10px; font-weight: 750; font-size: 13px; }
.poser-studio-foot-actions .primary { background: var(--brand-gradient, linear-gradient(135deg, #7c3aed, #4f63dd)); border: 0; color: #fff; box-shadow: 0 6px 16px rgba(124, 58, 237, .3); }

/* ===== 暗色主题：导演台（导演台 CSS 多为硬编码浅色，这里按全站 body.theme-dark 调色板覆盖；浅色模式不受影响）
   调色：面板 surface 令牌(已暗) / 输入 rgba(15,23,42,.6) / 按钮 rgba(32,36,46,.55) / 边框 rgba(83,90,104,.5) / 文字 #dbe7f5·次级 #9db0c8 / 强调保持紫 ===== */
body.theme-dark .poser-studio-bar { background: linear-gradient(180deg, #1b1f29, #12151d); }
body.theme-dark .poser-studio-foot { background: #12151d; }
body.theme-dark .poser-studio-stage { background: radial-gradient(120% 100% at 50% 0%, #1b1f29 0%, #0e1016 100%); }
body.theme-dark .poser-runtime-overlay { background: rgba(8, 12, 20, .76); }
body.theme-dark .poser-runtime-card { background: rgba(18, 24, 35, .95); border-color: rgba(100, 116, 139, .42); color: #e6edf7; box-shadow: 0 18px 55px rgba(0, 0, 0, .44); }
body.theme-dark .poser-runtime-head span, body.theme-dark .poser-runtime-meta { color: #9db0c8; }
body.theme-dark .poser-runtime-error { color: #ffb4ab; }
body.theme-dark .poser-studio-brandtext strong { color: #eaf2fb; }
body.theme-dark .poser-studio-sec, body.theme-dark .poser-insp-seclabel { color: #c4d2e2; }
body.theme-dark .poser-stage-hint, body.theme-dark .poser-shot-empty, body.theme-dark .poser-insp-hint, body.theme-dark .poser-studio-foot-hint, body.theme-dark .poser-add-label { color: #7e93ad; }
body.theme-dark .poser-insp-flabel, body.theme-dark .poser-insp-tab, body.theme-dark .poser-insp-axis-label, body.theme-dark .poser-frame-label { color: #9db0c8; }
body.theme-dark .poser-insp-tab.active { color: #fff; }
body.theme-dark .poser-insp-tabs { border-bottom-color: rgba(83,90,104,.5); }
/* 输入 / 单元格 / 数值 / 十六进制 / 体型下拉 / 焦距光圈 */
body.theme-dark :is(.poser-insp-cell, .poser-insp-name, .poser-insp-color, .poser-insp-uni-val, .poser-insp-colorhex, .poser-num, .poser-build-select) { background: rgba(15,23,42,.6); border-color: rgba(83,90,104,.5); color: #dbe7f5; }
body.theme-dark .poser-insp-cell input { color: #dbe7f5; }
body.theme-dark .poser-insp-cell i { color: #7e93ad; }
/* 按钮 / 工具 / 动作格 / 机位行 / 画幅按钮（不含顶栏模式胶囊，它另有样式）*/
body.theme-dark :is(.poser-tool, .poser-ghost-btn, .poser-iconbtn, .poser-pose-btn, .poser-frame-btn, .poser-shot) { background: rgba(32,36,46,.55); border-color: rgba(83,90,104,.5); color: #c4d2e2; }
body.theme-dark .poser-pose-btn span { color: #9db0c8; }
body.theme-dark .poser-pose-btn:first-child { background: rgba(124,58,237,.16); border-color: rgba(124,58,237,.45); }
body.theme-dark .poser-pose-new { background: rgba(124,58,237,.16); border-color: rgba(124,58,237,.5); color: #c4b5fd; }
body.theme-dark .poser-pose-custom { background: rgba(240,160,75,.14); border-color: rgba(240,160,75,.4); }
body.theme-dark .poser-studio-modes { background: rgba(15,23,42,.5); border-color: rgba(83,90,104,.5); }
/* 顶栏「重置姿势/重置视角」等 ghost 按钮、撤回图标按钮 hover 保持紫 */
body.theme-dark :is(.poser-tool, .poser-ghost-btn, .poser-iconbtn, .poser-frame-btn):hover { color: var(--poser-accent); border-color: var(--poser-accent); }
/* 演员卡片 */
body.theme-dark .poser-actor { background: rgba(18,21,28,.7); border-color: rgba(83,90,104,.5); }
body.theme-dark .poser-actor.selected { background: rgba(124,58,237,.16); border-color: var(--poser-accent); box-shadow: inset 0 0 0 1px var(--poser-accent); }
body.theme-dark .poser-actor .poser-actor-name { color: #e7eef9; }
body.theme-dark .poser-actor .poser-actor-name:focus { background: rgba(15,23,42,.85); }
body.theme-dark .poser-frame-mask { border-color: rgba(255,255,255,.5); }
@media (max-width: 860px) {
  .poser-studio-main { display: flex; flex-direction: column; overflow: auto; }
  .poser-studio-stage { order: -1; min-height: 46vh; }
  .poser-studio-left { border-right: 0; border-bottom: 1px solid var(--border); }
  .poser-studio-right { border-left: 0; }
  .poser-studio-bar { flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
  .poser-studio-brandtext span { display: none; }
  .poser-studio-modes { order: 3; width: 100%; justify-content: space-between; }
  .poser-studio-modes .poser-mode { flex: 1 1 auto; justify-content: center; padding: 7px 8px; }
  .poser-studio-foot { display: flex; flex-wrap: wrap; justify-content: space-between; padding: 10px 12px; }
  .poser-studio-foot-hint { display: none; }
  .poser-studio-foot-actions { width: 100%; }
  .poser-studio-foot-actions .secondary, .poser-studio-foot-actions .primary { flex: 1 1 auto; }
  .poser-runtime-overlay { display: grid; padding: 12px; }
  .poser-runtime-overlay[hidden] { display: none !important; }
  .poser-runtime-card { width: min(360px, 96%); padding: 15px 16px; }
  .poser-reverse-btn span:last-child { display: none; }
  .poser-reverse-btn { width: 32px; height: 32px; padding: 0; justify-content: center; }
}

.infinite-card-summary {
  display: grid;
  gap: 7px;
  min-height: 84px;
  padding: 4px 2px;
}

.infinite-card-summary strong {
  color: #142033;
  font-size: 13px;
  line-height: 1.3;
}

.infinite-card-summary span,
.infinite-card-summary small {
  color: #506176;
  font-size: 12px;
  line-height: 1.45;
}

.infinite-card-summary span {
  display: -webkit-box;
  min-height: 34px;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.infinite-card-summary small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 模块空态：撑满卡身、整体垂直+水平居中的图标占位 + 行动召唤 + 参考胶囊。颜色跟随模块 --card-accent。 */
.infinite-card-summary.infinite-card-empty {
  justify-items: center;
  align-content: center;
  gap: 11px;
  padding: 14px 12px;
}
/* 图标占位:强调色柔和渐变方块 + 内描边 + 轻投影,做得更精致有层次 */
.infinite-card-empty .infinite-card-empty-icon {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  min-height: 0;
  border-radius: 16px;
  background: linear-gradient(150deg, color-mix(in srgb, var(--card-accent, var(--accent)) 22%, #fff) 0%, color-mix(in srgb, var(--card-accent, var(--accent)) 9%, #fff) 100%);
  color: var(--card-accent, var(--accent));
  box-shadow: 0 6px 16px color-mix(in srgb, var(--card-accent, var(--accent)) 20%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--card-accent, var(--accent)) 16%, transparent);
}
.infinite-card-empty .infinite-card-empty-icon svg {
  width: 26px;
  height: 26px;
}
/* 提示文案:深一点、字重加大,作为清晰的行动召唤 */
.infinite-card-empty .infinite-card-empty-hint {
  display: block;
  min-height: 0;
  -webkit-line-clamp: unset;
  text-align: center;
  color: #3f4a5c;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.45;
  max-width: 94%;
}
/* 参考媒体:做成一颗强调色轻胶囊,而非零散灰字 */
.infinite-card-empty .infinite-card-empty-refs {
  display: inline-flex;
  align-items: center;
  color: var(--card-accent, var(--accent));
  font-size: 11px;
  font-weight: 650;
  padding: 3px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--card-accent, var(--accent)) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--card-accent, var(--accent)) 20%, transparent);
}

.infinite-card-inline-panel {
  position: absolute;
  z-index: 35;
  display: grid;
  gap: 8px;
  padding: 10px;
  max-height: min(420px, calc(100% - 22px));
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid rgba(203, 213, 225, 0.92);
  border-top: 4px solid var(--card-accent, #2f6db7);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 22px 52px rgba(15, 23, 42, 0.15);
  color: var(--text);
  pointer-events: auto;
  user-select: text;
  transform-origin: 32px 0;
  animation: infiniteCanvasPanelIn 150ms ease-out both;
  will-change: opacity, transform;
}

/* 刷新已打开的同一面板(连线接入参考图/改设置导致重建)时不重放入场动画——无缝换内容,避免「编辑框闪一下刷新」。 */
.infinite-card-inline-panel.no-enter-anim {
  animation: none;
}

.infinite-card-inline-panel::before {
  content: "";
  position: absolute;
  top: -10px;
  left: 28px;
  width: 16px;
  height: 16px;
  border-left: 1px solid rgba(203, 213, 225, 0.92);
  border-top: 1px solid rgba(203, 213, 225, 0.92);
  background: rgba(255, 255, 255, 0.98);
  transform: rotate(45deg);
}

.infinite-card-inline-panel.closing {
  pointer-events: none;
  animation: infiniteCanvasPanelOut 140ms ease-in both;
}

@keyframes infiniteCanvasPanelIn {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.985);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes infiniteCanvasPanelOut {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }

  to {
    opacity: 0;
    transform: translateY(-6px) scale(0.985);
  }
}

@media (prefers-reduced-motion: reduce) {
  .infinite-card-inline-panel,
  .infinite-card-inline-panel.closing {
    animation: none;
  }
}

.infinite-inline-panel-head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.infinite-inline-panel-head strong {
  color: #101828;
  font-size: 14px;
  line-height: 1.25;
}

.infinite-inline-panel-head span {
  color: #667085;
  font-size: 12px;
  white-space: nowrap;
}

.infinite-inline-panel-body {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 8px;
  padding: 0;
}

.infinite-inline-panel-body textarea {
  width: 100%;
  min-height: 120px;
  overflow-y: auto;
  box-sizing: border-box;
}

.infinite-card-inline-panel:has(.infinite-card-run) {
  max-height: min(390px, calc(100% - 22px));
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "refs"
    "prompt"
    "fields"
    "actions"
    "note";
  align-items: stretch;
}

.infinite-inline-prompt-expand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > textarea {
  grid-area: prompt;
  min-height: 150px;
  max-height: 178px;
  border-radius: 14px;
  padding: 11px 48px 11px 12px;
  resize: none;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > .infinite-inline-prompt-expand {
  grid-area: prompt;
  z-index: 2;
  align-self: end;
  justify-self: end;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > .infinite-inline-references {
  grid-area: refs;
  min-height: 64px;
  padding: 6px 8px;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > .infinite-card-note {
  grid-area: note;
  min-height: 0;
  padding: 7px 10px;
  border-radius: 12px;
  background: #f7fafd;
  color: #5f7287;
  font-size: 12px;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > .infinite-card-fields {
  grid-area: fields;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  align-self: stretch;
  align-content: start;
}

.infinite-card-inline-panel:has(.infinite-card-run) .infinite-inline-panel-body > .infinite-card-actions {
  grid-area: actions;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  justify-self: start;
}

.infinite-inline-panel-body .infinite-card-fields {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.infinite-inline-panel-body .infinite-card-field {
  grid-template-columns: 62px minmax(0, 1fr);
}

.infinite-inline-panel-body .infinite-card-run {
  justify-self: start;
  width: auto;
  min-width: 128px;
  padding-inline: 18px;
}

.infinite-card-run {
  width: 100%;
  min-height: 34px;
}

.infinite-card-media {
  display: grid;
  gap: 8px;
  cursor: default;
  user-select: none;
  -webkit-user-drag: none;
}

.infinite-card-media-box {
  min-height: 150px;
  border: 1px dashed #cbd8e7;
  border-radius: 10px;
  background: #f8fbfd;
  padding: 8px;
}

.infinite-card-media-box.drag-over {
  border-color: #2f6db7;
  background: #eaf2fb;
}

.infinite-card-drop-zone {
  display: grid;
  place-items: center;
  min-height: 130px;
  color: #6b7890;
  text-align: center;
  line-height: 1.55;
  font-size: 12px;
}

.infinite-card-media-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

.infinite-card-media-grid button {
  min-height: 72px;
  padding: 0;
  border: 1px solid #dbe7f0;
  border-radius: 8px;
  background: #ffffff;
  overflow: hidden;
  cursor: default;
  user-select: none;
  -webkit-user-drag: none;
}

.infinite-card-media:hover,
.infinite-card-media-grid button:hover {
  cursor: zoom-in;
}

.infinite-card-media img,
.infinite-card-media video,
.infinite-card-media-grid img,
.infinite-card-media-grid video {
  width: 100%;
  max-height: 160px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid #e0e8f3;
  background: #f4f7fb;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
  pointer-events: none;
}

/* 手机端双击画布媒体进入原位编辑时，两次触摸间隙会触发浏览器/系统原生长按菜单
   （iOS 图片 callout / 安卓保存图片）。iOS 的 callout 不发 contextmenu，JS 拦不住，
   唯一可靠的是无条件 -webkit-touch-callout:none —— 直接钉在媒体贴片与其容器上，
   不再依赖 styles.part4.css 里被 @media(max-width:820px)+宿主作用域限死的那条规则。 */
.infinite-card-media,
.infinite-card-media-grid,
.infinite-card-media-grid button,
[data-canvas-card-media],
[data-canvas-media-drag] {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* 媒体卡单图/视频填满卡片：去掉 160px 上限并撑满卡片高度，拉大后不再留白边 */
.infinite-card.media-card,
.infinite-card.panorama-view-card {
  display: flex;
  flex-direction: column;
}

.infinite-card.media-card .infinite-card-body,
.infinite-card.panorama-view-card .infinite-card-body {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}

.infinite-card.media-card .infinite-card-media {
  height: 100%;
  min-height: 0;
}

.infinite-card.media-card .infinite-card-media img,
.infinite-card.media-card .infinite-card-media video {
  height: 100%;
  max-height: none;
}

.infinite-card.media-card .infinite-card-media video {
  object-fit: contain;
  background: #070b10;
}

.infinite-card-media.panorama img {
  aspect-ratio: 2 / 1;
  object-fit: cover;
}

.infinite-card.panorama-view-card .infinite-card-body {
  padding: 0;
}

/* 全景预览要像图片/视频卡一样占满整张模块：不留内边距、不画边框/内阴影，只把底部圆角和卡片对齐。 */
.infinite-card-panorama {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  border: 0;
  border-radius: 0 0 9px 9px;
  overflow: hidden;
  cursor: zoom-in;
  background:
    radial-gradient(circle at center, rgba(47, 109, 183, 0.10), transparent 62%),
    linear-gradient(135deg, #f8fbff, #edf6ff);
  user-select: none;
  touch-action: manipulation;
}

.infinite-card-panorama.dragging {
  cursor: zoom-in;
}

.infinite-card-panorama-image,
.infinite-card-panorama canvas {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: cover;
  pointer-events: none;
}

.infinite-card-panorama-hint {
  position: absolute;
  left: 9px;
  bottom: 8px;
  padding: 4px 8px;
  border: 1px solid rgba(255, 255, 255, 0.38);
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.46);
  color: #ffffff;
  font-size: 11px;
  font-weight: 760;
  backdrop-filter: blur(8px);
  pointer-events: none;
}

.infinite-card-media-grid img,
.infinite-card-media-grid video {
  height: 72px;
  max-height: 72px;
  border: 0;
  border-radius: 0;
}

.infinite-generated-media {
  margin-bottom: 8px;
}

.infinite-generated-media.single .infinite-card-media-grid {
  grid-template-columns: 1fr;
}

.infinite-generated-media.single .infinite-card-media-grid button {
  min-height: 150px;
}

.infinite-generated-media.single .infinite-card-media-grid img,
.infinite-generated-media.single .infinite-card-media-grid video {
  height: auto;
  max-height: 340px;
  aspect-ratio: inherit;
  border-radius: 10px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card[data-canvas-type="playlist"] > .infinite-card-body {
  flex: 1 1 auto;
  min-height: 0;
  padding: 0;
  overflow: hidden;
  border-radius: 7px;
  background: var(--surface-2);
}

body:not(.auth-required) .layout.canvas-layout .infinite-card[data-canvas-type="playlist"] {
  display: flex;
  flex-direction: column;
}

.infinite-playlist-box {
  --pl-bg: var(--surface-2);
  --pl-panel: var(--surface);
  --pl-raised: var(--surface-3);
  --pl-border: var(--border);
  --pl-text: var(--text);
  --pl-muted: var(--muted);
  --pl-accent: var(--accent);
  --pl-accent-solid: var(--accent);
  --pl-stage: #070b10;
  position: relative;
  min-width: 0;
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 10px;
  overflow: hidden;
  border-radius: 7px;
  background: var(--pl-bg);
  color: var(--pl-text);
}

body.theme-dark .infinite-playlist-box {
  --pl-accent: #72b7ff;
  --pl-accent-solid: #2f6db7;
}

/* 「移动把手」:整卡塞满控件时,非交互结构区(边距/分区标题/空白间隙)也能拖动整卡。
   真实控件(播放器/传输条/镜头/按钮/输入)保留自身指针,避免误导。 */
.infinite-playlist-box[data-canvas-move-handle] { cursor: grab; }
.infinite-playlist-box[data-canvas-move-handle] [data-canvas-playback-control],
.infinite-playlist-box[data-canvas-move-handle] .infinite-playlist-thumb,
.infinite-playlist-box[data-canvas-move-handle] input,
.infinite-playlist-box[data-canvas-move-handle] label { cursor: auto; }
.infinite-playlist-box[data-canvas-move-handle] button { cursor: pointer; }

.infinite-playlist-summary {
  min-height: 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.infinite-playlist-summary strong { color: var(--pl-text); font-size: 13px; letter-spacing: 0.01em; }
.infinite-playlist-summary span { color: var(--pl-muted); font-size: 11px; font-variant-numeric: tabular-nums; }

.infinite-playlist-player {
  position: relative;
  flex: 1 1 260px;
  min-height: 220px;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--pl-border) 76%, #26384d);
  border-radius: 9px;
  background: var(--pl-stage);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.025);
}

.infinite-playlist-box.drag-over .infinite-playlist-player,
.infinite-playlist-box.drag-over .infinite-playlist-track {
  border-color: #63a4ee;
  box-shadow: 0 0 0 2px rgba(74, 145, 224, 0.22);
}

.infinite-playlist-player > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  display: block;
  aspect-ratio: auto !important;
  background: var(--pl-stage);
  object-position: 50% 50%;
}

.infinite-playlist-player[data-playlist-fit="contain"] > video { object-fit: contain !important; }
.infinite-playlist-player[data-playlist-fit="cover"] > video { object-fit: cover !important; }

.infinite-playlist-player:focus-visible {
  outline: 2px solid var(--pl-accent);
  outline-offset: 2px;
}

.infinite-playlist-status {
  flex: 0 0 auto;
  color: var(--pl-muted);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.infinite-playlist-current-name {
  position: absolute;
  left: 10px;
  bottom: 9px;
  max-width: calc(100% - 20px);
  padding: 4px 8px;
  overflow: hidden;
  border-radius: 5px;
  background: rgba(4, 8, 13, 0.72);
  color: #f8fafc;
  font-size: 11px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
  backdrop-filter: blur(8px);
}

.infinite-playlist-empty-state {
  display: grid;
  place-items: center;
  gap: 5px;
  color: var(--pl-muted);
  text-align: center;
}

.infinite-playlist-empty-state svg { width: 28px; height: 28px; }
.infinite-playlist-empty-state strong { color: var(--pl-text); font-size: 13px; }
.infinite-playlist-empty-state span { font-size: 11px; }

.infinite-playlist-transport {
  min-width: 0;
  display: grid;
  gap: 5px;
  padding: 6px 7px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel);
}

.infinite-playlist-transport-main {
  min-width: 0;
  display: grid;
  grid-template-columns: auto minmax(120px, 1fr) auto;
  align-items: center;
  gap: 8px;
}

.infinite-playlist-transport-buttons,
.infinite-playlist-transport-options {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.infinite-playlist-transport-meta {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.infinite-playlist-transport-options { margin-left: auto; }

.infinite-playlist-playback-state {
  color: var(--pl-accent);
  font-size: 10px;
  font-weight: 750;
}

.infinite-playlist-transport button,
.infinite-playlist-trim button,
.infinite-playlist-bgm-toggle {
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  background: var(--pl-raised);
  color: var(--pl-text);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}

.infinite-playlist-transport button:hover:not(:disabled),
.infinite-playlist-trim button:hover:not(:disabled),
.infinite-playlist-bgm-toggle:hover:not(:disabled) { border-color: var(--pl-accent); color: var(--pl-accent); }
.infinite-playlist-transport button:disabled,
.infinite-playlist-trim button:disabled { opacity: 0.38; cursor: default; }
.infinite-playlist-transport button.primary { min-width: 54px; border-color: var(--pl-accent-solid); background: var(--pl-accent-solid); color: #fff; }
.infinite-playlist-transport button:focus-visible,
.infinite-playlist-trim button:focus-visible,
.infinite-playlist-bgm-toggle:focus-visible { outline: 2px solid var(--pl-accent); outline-offset: 2px; }

.infinite-playlist-video-scrub {
  --video-progress: 0%;
  --video-buffered: 0%;
  width: 100%;
  min-width: 0;
  min-height: 0 !important;
  max-height: 26px !important;
  height: 26px;
  margin: 0;
  padding: 0 !important;
  border: 0 !important;
  appearance: none;
  background: transparent !important;
  box-shadow: none !important;
  cursor: pointer;
}

.infinite-playlist-video-scrub::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--pl-accent) 0 var(--video-progress), color-mix(in srgb, var(--pl-muted) 42%, transparent) var(--video-progress) var(--video-buffered), color-mix(in srgb, var(--pl-muted) 20%, transparent) var(--video-buffered) 100%);
}

.infinite-playlist-video-scrub::-webkit-slider-thumb {
  width: 14px;
  height: 14px;
  margin-top: -5px;
  appearance: none;
  border: 2px solid var(--pl-panel);
  border-radius: 50%;
  background: var(--pl-accent);
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.28);
}

.infinite-playlist-video-scrub::-moz-range-track { height: 4px; border-radius: 999px; background: color-mix(in srgb, var(--pl-muted) 20%, transparent); }
.infinite-playlist-video-scrub::-moz-range-progress { height: 4px; border-radius: 999px; background: var(--pl-accent); }
.infinite-playlist-video-scrub::-moz-range-thumb { width: 12px; height: 12px; border: 2px solid var(--pl-panel); border-radius: 50%; background: var(--pl-accent); }
.infinite-playlist-video-scrub:focus-visible { outline: 2px solid var(--pl-accent); outline-offset: 1px; border-radius: 999px; }
.infinite-playlist-video-scrub:disabled { opacity: 0.4; cursor: default; }

.infinite-playlist-timecode {
  flex: 0 0 auto;
  color: var(--pl-text);
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.infinite-playlist-trim {
  min-height: 30px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 9px;
  border: 1px solid var(--pl-border);
  border-radius: 7px;
  background: var(--pl-panel);
}

.infinite-playlist-trim > span { flex: 1 1 auto; color: var(--pl-muted); font-size: 11px; }
.infinite-playlist-trim b { color: var(--pl-text); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-weight: 650; }

.infinite-playlist-track {
  min-width: 0;
  padding: 7px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

.infinite-playlist-track-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
  color: var(--pl-muted);
  font-size: 10px;
}

.infinite-playlist-track-label { display: inline-flex; align-items: center; gap: 6px; color: var(--pl-text); }
.infinite-playlist-track-label svg { width: 14px; height: 14px; color: var(--pl-accent); }
.infinite-playlist-track-label strong { font-size: 11px; }

.infinite-playlist-strip {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  min-height: 92px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-inline: contain;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--pl-muted) 54%, transparent) transparent;
}

.infinite-playlist-strip.empty { align-items: center; justify-content: center; color: var(--pl-muted); font-size: 11px; }

.infinite-playlist-thumb {
  position: relative;
  width: var(--playlist-clip-width, 144px);
  height: 96px;
  flex: 0 0 var(--playlist-clip-width, 144px);
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  border-radius: 7px;
  background: var(--pl-raised);
  cursor: grab;
  transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease;
}

.infinite-playlist-thumb.active {
  border-color: var(--pl-accent);
  box-shadow: 0 0 0 2px rgba(74, 145, 224, 0.22);
}

.infinite-playlist-thumb:focus-visible { outline: 2px solid var(--pl-accent); outline-offset: 2px; }

.infinite-playlist-thumb.dragging {
  opacity: 0.55;
  transform: scale(0.96);
  cursor: grabbing;
}

.infinite-playlist-thumb.will-remove {
  opacity: 0.4;
  border-color: #d9534f;
  box-shadow: 0 0 0 2px rgba(217, 83, 79, 0.32);
}

.infinite-playlist-thumb.placeholder {
  opacity: 0.25;
}

.playlist-thumb-ghost {
  position: fixed;
  z-index: var(--z-drag-ghost);
  margin: 0;
  pointer-events: none;
  overflow: hidden;
  border: 2px solid #2f6db7;
  border-radius: 8px;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.34);
  transform: scale(1.05);
  opacity: 0.96;
}

.playlist-thumb-ghost .infinite-playlist-thumb-index {
  display: none;
}

.playlist-thumb-ghost.will-remove {
  border-color: #d9534f;
  box-shadow: 0 10px 24px rgba(217, 83, 79, 0.42);
}

.infinite-playlist-thumb.drop-target {
  border-color: #2f6db7;
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.16);
}

.infinite-playlist-strip.drop-target {
  outline: 2px dashed rgba(47, 109, 183, 0.5);
  outline-offset: 2px;
  border-radius: 8px;
}

.infinite-playlist-thumb video,
.infinite-playlist-thumb img {
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.infinite-playlist-thumb video { object-fit: contain; background: #070b10; }
.infinite-playlist-thumb img { object-fit: cover; }

.infinite-playlist-thumb-preview {
  position: relative;
  height: 68px;
  overflow: hidden;
  background: #070b10;
}

.infinite-playlist-thumb-info {
  height: 27px;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 26px 0 7px;
  color: var(--pl-text);
  font-size: 10px;
}

.infinite-playlist-thumb-info > span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-playlist-thumb-info time { flex: 0 0 auto; color: var(--pl-muted); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; }

.infinite-playlist-remove {
  width: 23px;
  height: 23px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--pl-muted);
  cursor: pointer;
}

.infinite-playlist-thumb > .infinite-playlist-remove { position: absolute; right: 3px; bottom: 2px; }
.infinite-playlist-remove:hover { background: rgba(225, 85, 85, 0.14); color: #f08b8b; }
.infinite-playlist-remove svg { width: 14px; height: 14px; }

.infinite-playlist-trimmed {
  position: absolute;
  right: 4px;
  top: 4px;
  padding: 2px 4px;
  border-radius: 4px;
  background: rgba(44, 116, 184, 0.88);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  pointer-events: none;
}

.infinite-playlist-thumb-index {
  position: absolute;
  top: 3px;
  left: 3px;
  z-index: 2;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: rgba(4, 8, 13, 0.78);
  color: #ffffff;
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
  pointer-events: none;
}

.infinite-playlist-bgm {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 63px;
  padding: 7px 8px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel);
}

.infinite-playlist-bgm.empty {
  min-height: 48px;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  border-style: dashed;
}

.infinite-playlist-bgm-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.infinite-playlist-bgm-empty {
  color: var(--pl-muted);
  font-size: 11px;
}

.infinite-playlist-bgm-controls {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.infinite-playlist-bgm-controls label {
  min-width: 0;
  display: grid;
  grid-template-columns: auto minmax(70px, 1fr);
  align-items: center;
  gap: 7px;
  color: var(--pl-muted);
  font-size: 10px;
}

.infinite-playlist-bgm-controls input {
  width: 100%;
  min-width: 0;
  min-height: 0 !important;
  max-height: 24px !important;
  height: 24px;
  margin: 0;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  accent-color: var(--pl-accent);
  cursor: pointer;
}

body.theme-dark:not(.auth-required) .infinite-card-video-controls input[type="range"],
body.theme-dark:not(.auth-required) .infinite-playlist-video-scrub,
body.theme-dark:not(.auth-required) .infinite-playlist-bgm-controls input[type="range"] {
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.infinite-playlist-bgm-toggle {
  flex: 0 0 auto;
  min-width: 46px;
}

.infinite-playlist-bgm-label {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--pl-text);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.infinite-playlist-bgm audio {
  display: none;
}

.panorama-preview-panel {
  width: min(1120px, calc(100vw - 36px));
  height: min(760px, calc(100dvh - 34px));
  max-height: calc(100dvh - 34px);
  display: grid;
  /* 头部 auto / 舞台占满剩余 1fr / 底部工具条 auto —— 舞台不再用固定 2:1 撑高，工具条永远在视野内 */
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 12px;
}

.panorama-preview-stage {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 0;
  border: 1px solid #c8d7e8;
  border-radius: 14px;
  background-color: #eef4f8;
  background-repeat: repeat-x;
  background-position: 50% 50%;
  overflow: hidden;
  cursor: grab;
  /* 触摸拖拽/捏合环视:必须 none,否则浏览器把触摸当滚动/缩放截走 → 手机端「拖不动视角」 */
  touch-action: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
/* 全景缩放控件:浮在 stage 右下角,桌面(无滚轮也能点)+手机通用 */
.panorama-zoom-ctrl {
  position: absolute; right: 12px; bottom: 12px; z-index: 3;
  display: inline-flex; align-items: center; gap: 2px; padding: 4px;
  border-radius: 999px; background: rgba(15, 23, 42, 0.62);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}
.panorama-zoom-ctrl button {
  display: inline-grid; place-items: center; width: 30px; height: 30px;
  border: 0; border-radius: 999px; background: transparent; color: #fff;
  font-size: 18px; font-weight: 700; line-height: 1; cursor: pointer;
}
.panorama-zoom-ctrl button:hover { background: rgba(255, 255, 255, 0.18); }
.panorama-zoom-ctrl button:active { background: rgba(255, 255, 255, 0.28); }
.panorama-zoom-ctrl [data-panorama-zoom-val] {
  min-width: 42px; text-align: center; color: #fff; font-size: 12px;
  font-weight: 600; font-variant-numeric: tabular-nums;
}

#panoramaPreviewCanvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.panorama-preview-stage.dragging {
  cursor: grabbing;
}

.panorama-preview-stage::before,
.panorama-preview-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.panorama-preview-stage::before {
  background: radial-gradient(circle at 50% 50%, transparent 45%, rgba(5, 18, 34, 0.22));
}

.panorama-preview-stage::after {
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: inherit;
}

.panorama-preview-hint {
  position: absolute;
  left: 16px;
  bottom: 14px;
  z-index: 2;
  padding: 7px 10px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.62);
  color: #ffffff;
  font-size: 12px;
}

.panorama-preview-tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: #607089;
  font-size: 12px;
}

/* —— 全景查看器 HUD：朝向罗盘 + 视野读数 —— */
.panorama-preview-hud {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  pointer-events: none;
}

.panorama-compass {
  position: relative;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 2px 10px rgba(5, 18, 34, 0.3);
}

.panorama-compass b {
  position: absolute;
  left: 50%;
  top: 3px;
  transform: translateX(-50%);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  opacity: 0.92;
}

.panorama-compass-needle {
  position: absolute;
  inset: 0;
  display: block;
  transform-origin: 50% 50%;
  transition: transform 0.06s linear;
}

.panorama-compass-needle::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 6px;
  transform: translateX(-50%);
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 14px solid #ff6b6b;
}

.panorama-compass-needle::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 14px solid rgba(255, 255, 255, 0.72);
}

.panorama-readout {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.panorama-readout span {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.55);
  color: #fff;
  font-size: 11px;
  line-height: 1;
}

.panorama-readout i {
  font-style: normal;
  opacity: 0.7;
}

.panorama-readout strong {
  font-variant-numeric: tabular-nums;
}

/* —— 截图取景框：框外压暗 + 三分构图线，框里=截出来 —— */
.panorama-frame-guide {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  border: 1.5px solid rgba(255, 255, 255, 0.95);
  border-radius: 3px;
  box-shadow: 0 0 0 100vmax rgba(8, 14, 26, 0.46);
  pointer-events: none;
}

.panorama-frame-guide::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to right, transparent calc(33.33% - 0.5px), rgba(255, 255, 255, 0.26) calc(33.33% - 0.5px), rgba(255, 255, 255, 0.26) calc(33.33% + 0.5px), transparent calc(33.33% + 0.5px)),
    linear-gradient(to right, transparent calc(66.66% - 0.5px), rgba(255, 255, 255, 0.26) calc(66.66% - 0.5px), rgba(255, 255, 255, 0.26) calc(66.66% + 0.5px), transparent calc(66.66% + 0.5px)),
    linear-gradient(to bottom, transparent calc(33.33% - 0.5px), rgba(255, 255, 255, 0.26) calc(33.33% - 0.5px), rgba(255, 255, 255, 0.26) calc(33.33% + 0.5px), transparent calc(33.33% + 0.5px)),
    linear-gradient(to bottom, transparent calc(66.66% - 0.5px), rgba(255, 255, 255, 0.26) calc(66.66% - 0.5px), rgba(255, 255, 255, 0.26) calc(66.66% + 0.5px), transparent calc(66.66% + 0.5px));
}

/* —— 截图比例：分段控件（一排 chip 装在一条胶囊轨道里）—— */
.panorama-preview-tools {
  flex-wrap: wrap;
  padding-top: 2px;
}

.panorama-ratio-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 3px;
  flex: 1 1 auto;
  padding: 4px;
  background: #eef3f9;
  border: 1px solid #e1e9f2;
  border-radius: 999px;
}

.panorama-ratio-label {
  color: #7a889d;
  font-size: 12px;
  font-weight: 600;
  padding: 0 8px 0 6px;
}

.panorama-ratio-chip {
  min-width: 40px;
  padding: 5px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #475569;
  font-size: 12px;
  font-weight: 650;
  line-height: 1.35;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease, box-shadow 0.13s ease;
}

.panorama-ratio-chip:hover {
  background: #dfe8f4;
  color: #2f6db7;
}

.panorama-ratio-chip.is-active {
  background: #2f6db7;
  color: #fff;
  box-shadow: 0 1px 5px rgba(47, 109, 183, 0.38);
}

#capturePanoramaToCanvasBtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

#capturePanoramaToCanvasBtn svg {
  width: 15px;
  height: 15px;
}

/* —— 全屏沉浸：把整张卡片铺满屏幕，舞台占据中间，控件依旧可见 —— */
.panorama-preview-panel:fullscreen,
.panorama-preview-panel:-webkit-full-screen {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  border-radius: 0;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: #0b1220;
}

.panorama-preview-panel:fullscreen .modal-head h2,
.panorama-preview-panel:fullscreen .modal-head p {
  color: #e8eef7;
}

.panorama-preview-panel:fullscreen .panorama-preview-stage {
  aspect-ratio: auto;
  height: 100%;
  min-height: 0;
  border-radius: 0;
}

.infinite-inline-references {
  display: grid;
  gap: 8px;
  padding: 9px;
  border: 1px dashed #c9d8e8;
  border-radius: 12px;
  background: #f7fafd;
}

.infinite-inline-references.drag-over {
  border-color: #2f6db7;
  background: #eaf2fb;
}

.infinite-inline-references-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  color: #2f6db7;
  font-size: 12px;
}

.infinite-inline-references-head strong {
  font-size: 12px;
}

.infinite-inline-references-head span {
  color: #5f7287;
}

.infinite-inline-references-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.infinite-inline-references-actions .small {
  min-height: 28px;
  padding: 4px 10px;
  border-radius: 10px;
  font-size: 12px;
}

.infinite-inline-reference-grid {
  display: grid;
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: 5px;
}

.infinite-inline-reference-empty {
  grid-column: 1 / -1;
  display: grid;
  min-height: 48px;
  place-items: center;
  border: 1px dashed #d5e3ee;
  border-radius: 10px;
  color: #5f7287;
  font-size: 12px;
  line-height: 1.5;
  text-align: center;
  background: rgba(255, 255, 255, 0.74);
}

/* 参考瓦片与「画布选择」加号都是 div[role=button]（不是 <button>）：
   根因——它们做成 <button> 会被全局 :where(button){height/padding!important} 压扁成竖条，
   故改 div 并按 role/属性选择，彻底绕开全局按钮规则，无需 !important 强压 */
.infinite-inline-reference-grid > [role="button"] {
  min-height: 40px;
  padding: 0;
  border: 1px solid #dbe7f0;
  border-radius: 9px;
  background: #ffffff;
  overflow: hidden;
  cursor: grab;
  /* 参考瓦片走指针式拖动排序：必须关掉浏览器默认触摸手势，否则手机端一按就被当成滚动/平移、
     指针拖动收到 pointercancel 直接失败(表现为「参数列表根本拖不动」)。none = 拖动全交给 JS。 */
  touch-action: none;
  transition: transform 160ms ease, opacity 120ms ease, border-color 160ms ease, box-shadow 160ms ease;
  will-change: transform;
}

.infinite-inline-reference-grid .infinite-inline-reference-add {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 1px;
  border: 1px dashed rgba(47, 109, 183, 0.55);
  background: linear-gradient(180deg, #f6fbff 0%, #eef6ff 100%);
  color: #2f6db7;
  cursor: pointer;
  font-weight: 900;
}

.infinite-inline-reference-grid .infinite-inline-reference-add span {
  line-height: 1;
  font-size: 20px;
}

.infinite-inline-reference-grid .infinite-inline-reference-add:hover {
  transform: translateY(-1px);
  border-color: rgba(47, 109, 183, 0.58);
  background: #eaf2fb;
  color: #2f6db7;
  box-shadow: 0 8px 18px rgba(47, 109, 183, 0.1);
}

.infinite-inline-reference-grid .infinite-inline-reference-add.active {
  border-style: solid;
  border-color: rgba(47, 109, 183, 0.68);
  background: #eaf2fb;
  color: #2f6db7;
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.12);
}

.infinite-inline-reference-grid [data-canvas-panel-ref].dragging {
  /* 拿起来就是拿走了:原位**不留占位**,其余瓦片当场补位(让位由共用拖拽引擎写 transform)。
     用 visibility 而非 display/opacity——几何要留着(引擎的槽位快照按它算),
     但一个像素都不许画出来,否则就是「幽灵之外原地还有一个自己」。 */
  visibility: hidden;
}

.infinite-inline-reference-grid [data-canvas-panel-ref].removing {
  opacity: 0;
  transform: scale(0.86);
}

.infinite-inline-reference-grid img,
.infinite-inline-reference-grid video {
  width: 100%;
  height: 40px;
  object-fit: cover;
  display: block;
  /* 缩略图只是展示：所有指针交互(拖排序/双击预览)交给瓦片 div，
     视频不再接管悬停——否则 Chrome 在 <video> 上浮出画中画/媒体控件抢走点击 */
  pointer-events: none;
}

/* 音频瓦片：小方格放不下波形卡，画一个居中音频图标（compact 模式渲染 .infinite-card-audio-thumb） */
.infinite-card-audio-thumb {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, #eef3fb 0%, #e3ecf7 100%);
  color: #2f6db7;
}

.infinite-card-audio-thumb svg {
  width: 20px;
  height: 20px;
}

/* 删除参考媒体：去掉角落 ✕ 按钮，统一「拖到框外」删除（幽灵变红示意）。 */

/* 拖拽幽灵:共用引擎克隆被拖瓦片本身当幽灵(所见即所拖,不用再另画一份),
   这里只负责「拎起来」的外观。位置/尺寸由引擎写行内样式。拖出框外变红示意移除。 */
.infinite-inline-reference-ghost {
  z-index: var(--z-drag-ghost);
  margin: 0;
  pointer-events: none;
  border: 2px solid #2f6db7;
  border-radius: 11px;
  overflow: hidden;
  /* 浅底而非深色——半透明图/缩略图不会被压暗，与浅色 UI 一致 */
  background-color: #f1f5f9;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  box-shadow: 0 12px 26px rgba(15, 23, 42, 0.32);
  opacity: 0.97;
}

/* 克隆体内部的缩略图要撑满小幽灵(原瓦片里 img 是固定 40px 高) */
.infinite-inline-reference-ghost img,
.infinite-inline-reference-ghost video,
.infinite-inline-reference-ghost .infinite-card-audio-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.infinite-inline-reference-ghost.is-text {
  display: grid;
  place-items: center;
  padding: 6px;
  background-color: #ffffff;
  color: #2f6db7;
  font-size: 11px;
  font-weight: 800;
  text-align: center;
  word-break: break-all;
}

.infinite-inline-reference-ghost.is-audio {
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, #eef3fb 0%, #e3ecf7 100%);
  color: #2f6db7;
}

.infinite-inline-reference-ghost.is-audio svg {
  width: 22px;
  height: 22px;
}

.infinite-inline-reference-ghost.dragging-out {
  border-color: #d92d20;
  box-shadow: 0 14px 30px rgba(217, 45, 32, 0.42);
}

.infinite-card-audio {
  --audio-card-accent: #2f6db7;
  --audio-card-accent-soft: rgba(47, 109, 183, 0.10);
  --audio-card-border: #dbe7f0;
  --audio-card-bg: #ffffff;
  --audio-card-bg-soft: #f7fafc;
  --audio-card-text: #172033;
  --audio-card-muted: #66738a;
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  gap: 7px 10px;
  align-items: center;
  width: 100%;
  height: 112px;
  min-height: 92px;
  padding: 11px;
  border-radius: 8px;
  border: 1px solid var(--audio-card-border);
  background: linear-gradient(180deg, var(--audio-card-bg) 0%, var(--audio-card-bg-soft) 100%);
  color: var(--audio-card-text);
  font-weight: 800;
  overflow: hidden;
}

.infinite-card-audio audio {
  display: none;
}

.infinite-card-audio-icon {
  grid-column: 1;
  grid-row: 1;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: 1px solid rgba(47, 109, 183, 0.16);
  background: var(--audio-card-accent-soft);
  color: var(--audio-card-accent);
}

.infinite-card-audio-icon[data-canvas-audio-toggle] {
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}

.infinite-card-audio-icon[data-canvas-audio-toggle]:hover {
  background: var(--audio-card-accent);
  color: #ffffff;
}

.infinite-card-audio-icon[data-canvas-audio-toggle]:focus-visible {
  outline: 2px solid var(--audio-card-accent);
  outline-offset: 2px;
}

.infinite-card-audio-icon[data-canvas-audio-toggle]:active {
  transform: scale(0.96);
}

.infinite-card-audio-icon [data-canvas-audio-toggle-icon] {
  display: grid;
  place-items: center;
}

.infinite-card-audio-main {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  gap: 3px;
  min-width: 0;
}

.infinite-card-audio-title {
  min-width: 0;
  color: var(--audio-card-text);
  font-size: 12px;
  font-weight: 850;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-card-audio-icon svg {
  width: 17px;
  height: 17px;
  stroke-width: 2;
}

.infinite-card-audio-wave {
  grid-column: 1 / -1;
  grid-row: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  height: 22px;
}

.infinite-card-audio-wave i {
  width: 4px;
  height: 18px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.42);
  transform-origin: center;
}

.infinite-card-audio-wave i:nth-child(2) { height: 28px; }
.infinite-card-audio-wave i:nth-child(3) { height: 22px; }
.infinite-card-audio-wave i:nth-child(4) { height: 32px; }
.infinite-card-audio-wave i:nth-child(5) { height: 16px; }

.infinite-card-audio.playing .infinite-card-audio-wave i {
  animation: infiniteAudioPulse 720ms ease-in-out infinite alternate;
}

.infinite-card-audio.playing .infinite-card-audio-wave i:nth-child(2) { animation-delay: 80ms; }
.infinite-card-audio.playing .infinite-card-audio-wave i:nth-child(3) { animation-delay: 160ms; }
.infinite-card-audio.playing .infinite-card-audio-wave i:nth-child(4) { animation-delay: 240ms; }
.infinite-card-audio.playing .infinite-card-audio-wave i:nth-child(5) { animation-delay: 320ms; }

.infinite-card-audio-progress {
  grid-column: 1 / -1;
  grid-row: 3;
  width: 100%;
  height: 14px;
  margin: 0;
  accent-color: var(--audio-card-accent);
  cursor: pointer;
  touch-action: none;
}

.infinite-card-audio-progress::-webkit-slider-runnable-track {
  height: 5px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.18);
}

.infinite-card-audio-progress::-webkit-slider-thumb {
  width: 13px;
  height: 13px;
  margin-top: -4px;
  border: 2px solid #ffffff;
  border-radius: 50%;
  background: var(--audio-card-accent);
  box-shadow: 0 2px 8px rgba(47, 109, 183, 0.26);
}

.infinite-card-audio-progress::-moz-range-track {
  height: 5px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.18);
}

.infinite-card-audio-progress::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border: 2px solid #ffffff;
  border-radius: 50%;
  background: var(--audio-card-accent);
  box-shadow: 0 2px 8px rgba(47, 109, 183, 0.26);
}

.infinite-card-audio-status {
  min-width: 0;
  color: var(--audio-card-muted);
  font-size: 11px;
  font-weight: 750;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.infinite-card-audio.playing .infinite-card-audio-status {
  color: var(--audio-card-accent);
}

.infinite-card-audio.playing .infinite-card-audio-status::before {
  content: "正在播放 · ";
}

/* ── 画布音频播放器（拖入的音乐/音频模块）：黑胶唱片风 ─────────────────────
   左：黑胶唱片（播放时旋转），中心常驻播放/暂停钮；右：文件名 + 类型 + 可拖动进度条（已播放高亮）+ 时间。
   card 变体用独立类名（disc/body），不复用基础 tile 的 grid，两者互不影响。 */
.infinite-card-audio[data-canvas-audio-surface="card"] {
  display: flex;
  align-items: center;
  gap: 13px;
  height: 100%;
  min-height: 0;
  padding: 11px 14px;
  border: 0;
  border-radius: 0 0 9px 9px;
  background: linear-gradient(180deg, var(--audio-card-bg), var(--audio-card-bg-soft));
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-main {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 15px;
  min-width: 0;
  min-height: 0;
}

/* 黑胶唱片：盘面（-face）播放时旋转；中心播放钮（-icon）常驻不转 */
.infinite-card-audio-disc {
  flex: 0 0 auto;
  position: relative;
  box-sizing: border-box;
  width: 56px;
  height: 56px;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}

.infinite-card-audio-disc-face {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--audio-card-accent) 26%, #1b1f27) 0 14%, rgba(0, 0, 0, 0) 14.5%),
    repeating-radial-gradient(circle at 50% 50%, #262a33 0 1.5px, #14171d 1.5px 3.6px);
  box-shadow: 0 6px 16px rgba(15, 20, 32, 0.24), inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}

.infinite-card-audio[data-canvas-audio-surface="card"].playing .infinite-card-audio-disc-face {
  animation: icaVinylSpin 3.4s linear infinite;
}

@keyframes icaVinylSpin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .infinite-card-audio-disc-face { animation: none !important; }
}

.infinite-card-audio-disc-icon {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--audio-card-accent);
  color: #ffffff;
  box-shadow: 0 2px 8px rgba(15, 20, 32, 0.30);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.infinite-card-audio-disc:hover .infinite-card-audio-disc-icon { transform: scale(1.06); }
.infinite-card-audio-disc:active .infinite-card-audio-disc-icon { transform: scale(0.94); }
.infinite-card-audio-disc-icon svg { width: 15px; height: 15px; }

/* 焦点：不描硬边；仅中心钮加一圈很淡软光晕（配合 JS 鼠标点击后失焦，平时不显） */
.infinite-card-audio-disc:focus-visible { outline: none; }
.infinite-card-audio-disc:focus-visible .infinite-card-audio-disc-icon {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--audio-card-accent) 22%, transparent), 0 2px 8px rgba(15, 20, 32, 0.30);
}

.infinite-card-audio-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-title {
  font-size: 13.5px;
  font-weight: 800;
  color: var(--audio-card-text);
}

.infinite-card-audio-sub {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--audio-card-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 5px;
}

.infinite-card-audio-scrub {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-progress {
  width: 100%;
  height: 16px;
  margin: 0;
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-progress::-webkit-slider-runnable-track {
  background: linear-gradient(to right,
    var(--audio-card-accent) var(--audio-progress, 0%),
    rgba(47, 109, 183, 0.18) var(--audio-progress, 0%));
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-progress::-moz-range-progress {
  height: 5px;
  border-radius: 999px;
  background: var(--audio-card-accent);
}

.infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-status {
  align-self: flex-end;
  color: var(--audio-card-muted);
  font-size: 11.5px;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
}

.infinite-card-audio[data-canvas-audio-surface="card"].playing .infinite-card-audio-status {
  color: var(--audio-card-accent);
}

.infinite-card-media-grid .infinite-card-audio {
  height: 100%;
  min-height: 82px;
  padding: 9px;
  grid-template-columns: 30px minmax(0, 1fr);
  grid-template-rows: auto minmax(14px, 1fr) auto;
  gap: 5px 8px;
  border: 0;
  border-radius: 0;
}

.infinite-card-media-grid .infinite-card-audio-icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
}

.infinite-card-media-grid .infinite-card-audio-title {
  display: none;
}

.infinite-card-media-grid .infinite-card-audio-status {
  font-size: 11px;
}

.infinite-card-media-grid .infinite-card-audio-wave i {
  width: 3px;
  height: 14px;
}

.infinite-card-media-grid .infinite-card-audio-progress {
  height: 12px;
}

.infinite-card.media-card .infinite-card-media .infinite-card-audio {
  height: 100%;
  min-height: 0;
  border: 0;
  border-radius: 0 0 9px 9px;
}

@container (max-width: 220px) {
  .infinite-card-audio[data-canvas-audio-surface="card"] {
    padding: 10px;
    grid-template-columns: 34px minmax(0, 1fr);
    gap: 7px 9px;
  }

  .infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-icon {
    width: 34px;
    height: 34px;
    border-radius: 10px;
  }

  .infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-title {
    font-size: 11px;
  }

  .infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-status {
    font-size: 10px;
  }

  .infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-wave {
    height: 24px;
    gap: 4px;
  }

  .infinite-card-audio[data-canvas-audio-surface="card"] .infinite-card-audio-wave i {
    width: 4px;
    height: 16px;
  }
}

body.theme-dark .infinite-card-audio {
  --audio-card-accent: #78b3e8;
  --audio-card-accent-soft: rgba(120, 179, 232, 0.13);
  --audio-card-border: rgba(255, 255, 255, 0.10);
  --audio-card-bg: #151c27;
  --audio-card-bg-soft: #111822;
  --audio-card-text: #e6eef8;
  --audio-card-muted: #a6b5c6;
}

@keyframes infiniteAudioPulse {
  from { transform: scaleY(0.62); opacity: 0.62; }
  to { transform: scaleY(1.18); opacity: 1; }
}

.infinite-card-meta {
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-card-url {
  margin-bottom: 8px;
}

.infinite-card-shape textarea {
  min-height: 58px;
  text-align: center;
}

.infinite-canvas-status-row {
  position: absolute;
  left: 18px;
  right: auto;
  bottom: 18px;
  z-index: 19;
  display: flex;
  align-items: center;
  gap: 10px;
  width: auto;
  height: auto;
  border: 0;
  background: transparent;
  pointer-events: none;
}

.infinite-canvas-status-row > * {
  pointer-events: auto;
}

.infinite-canvas-status-row .file-summary,
.infinite-canvas-status-row .workflow-history-actions {
  min-height: 38px;
  border: 1px solid rgba(203, 213, 225, 0.9);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: none;
  backdrop-filter: blur(12px);
}

.infinite-canvas-status-row .file-summary {
  display: flex;
  align-items: center;
  padding: 0 14px;
  color: #526174;
}

.infinite-canvas-status-row .workflow-history-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
}

.infinite-canvas-status-row .workflow-history-actions button {
  min-height: 30px;
  border-radius: 999px;
}

.infinite-canvas-search {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-weight: 800;
}

.infinite-canvas-layer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
}

.infinite-canvas-layer-head h3 {
  margin: 0;
  font-size: 14px;
}

.infinite-canvas-layer-head span {
  color: var(--muted);
  font-size: 12px;
}

.infinite-canvas-layer-list {
  display: grid;
  gap: 6px;
  max-height: 260px;
  overflow: auto;
  margin-top: 8px;
}

.infinite-canvas-layer-item {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 7px 8px;
  border: 1px solid #dbe7f0;
  border-radius: 10px;
  background: #ffffff;
  text-align: left;
  cursor: pointer;
}

.infinite-canvas-layer-item:hover,
.infinite-canvas-layer-item.selected {
  border-color: rgba(47, 109, 183, 0.42);
  background: #eaf2fb;
}

.infinite-canvas-layer-item span:first-child {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--layer-accent, #2f6db7);
  color: #ffffff;
  font-size: 12px;
  font-weight: 900;
}

.infinite-canvas-layer-title {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.infinite-canvas-layer-title strong,
.infinite-canvas-layer-title small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.infinite-canvas-layer-title small {
  color: var(--muted);
  font-size: 11px;
}

.infinite-canvas-selection-info {
  display: grid;
  gap: 5px;
  padding: 10px;
  border: 1px solid #dbe7f0;
  border-radius: 10px;
  background: #ffffff;
  color: #344154;
  font-size: 12px;
}

.infinite-canvas-selection-info strong {
  color: var(--text);
  font-size: 14px;
}

.infinite-canvas-property-panel {
  display: grid;
  gap: 8px;
  margin-top: 10px;
}

.infinite-canvas-property-title {
  font-weight: 900;
  color: var(--text);
}

.infinite-canvas-property-row {
  display: grid;
  gap: 5px;
  font-size: 12px;
  color: #526174;
  font-weight: 800;
}

.infinite-canvas-property-row input,
.infinite-canvas-property-row select {
  width: 100%;
  min-height: 32px;
  border: 1px solid #d7e2ef;
  border-radius: 8px;
  background: #ffffff;
  padding: 4px 8px;
  font: inherit;
  font-weight: 700;
}

.infinite-canvas-property-row input[type="color"] {
  padding: 3px;
}

.infinite-canvas-property-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.infinite-canvas-property-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.infinite-canvas-property-actions button {
  min-height: 32px;
  border-radius: 8px;
  border: 1px solid #cad6e5;
  background: #ffffff;
  color: #1f3454;
  font-weight: 800;
}

.infinite-canvas-tip.compact {
  margin-top: 0;
  padding: 10px;
}

@media (max-width: 980px) {
  .infinite-canvas-shell {
    grid-template-columns: 1fr;
  }

  .infinite-canvas-sidebar,
  .infinite-canvas-inspector {
    display: none;
  }

  .infinite-canvas-toolbar {
    inset: 0;
  }

  .infinite-canvas-main {
    height: calc(100vh - 28px);
    min-height: 560px;
  }

  .canvas-ai-composer {
    grid-template-columns: 1fr;
  }

  .canvas-generate-options {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .canvas-board-row {
    left: 70px;
    right: 10px;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: end;
    max-height: none;
    overflow: visible;
  }

  .canvas-board-row > label {
    font-size: 0;
  }

  .canvas-board-row > label input,
  .canvas-board-row > label select {
    min-height: 34px;
    font-size: 13px;
  }

  .canvas-board-actions {
    grid-column: 1 / -1;
    justify-content: flex-start;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 2px;
  }

  .canvas-ai-composer {
    position: absolute;
    left: 70px;
    right: 10px;
    bottom: 58px;
    width: auto;
    max-width: none;
    margin: 0;
    transform: none;
    max-height: min(50vh, 380px);
    overflow: auto;
    align-items: stretch;
    padding: 10px;
  }

  .canvas-composer-ref-drop {
    min-height: 78px;
  }

  .canvas-composer-ref-drop > span {
    display: none;
  }

  .canvas-prompt-box textarea {
    min-height: 72px;
  }

  .canvas-composer-result {
    display: none;
  }

  .canvas-empty-card {
    width: calc(100% - 100px);
  }

  .canvas-empty-actions {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1120px) {
  body:not(.auth-required) .topbar {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--sidebar);
    height: 100vh;
    min-height: 100vh;
    border-right: 1px solid var(--border);
    border-bottom: 0;
  }

  body:not(.auth-required) .layout {
    margin-left: var(--sidebar);
  }
}

/* Infinite canvas final workspace polish: align with workflow, keep canvas-specific dock and media board behavior. */
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-shell.canvas-studio-shell {
  --canvas-surface: #f4f7fa;
  --canvas-glass-strong: rgba(255, 255, 255, 0.82);
  --canvas-glass-soft: rgba(255, 255, 255, 0.78);
  --canvas-border-strong: rgba(213, 220, 229, 0.9);
  --canvas-panel-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  --canvas-card-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 28px rgba(15, 23, 42, 0.07);
  display: grid;
  /* 右侧检查器已废弃(display:none)，不再保留 286px 空列；单列铺满 */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  /* 填满外层高度链(workbench→面板)，不再用 calc(100vh - 魔法数) */
  height: 100%;
  min-height: 0;
  overflow: hidden;
  /* 内层这层"壳"取消(不要壳套壳)：去掉自己的边框/圆角/阴影/底，只当透明填充，
     卡片外观交给最外面的 workbench(.panel)那一层。 */
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-main {
  position: relative;
  height: 100%;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border: 0;
  border-radius: 20px 0 0 20px;
  background: transparent;
  box-shadow: none;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-inspector {
  display: block;
  min-width: 0;
  height: 100%;
  padding: 18px 16px;
  overflow: auto;
  border-left: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 0 20px 20px 0;
  background: rgba(255, 255, 255, 0.86);
  box-shadow: none;
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-toolbar {
  position: absolute;
  inset: 0;
  z-index: 20;
  pointer-events: none;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
  position: absolute;
  top: 18px;
  left: 18px;
  right: 18px;
  z-index: 24;
  width: auto;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(140px, 180px) minmax(180px, 1fr) auto;
  gap: 8px 10px;
  align-items: end;
  padding: 10px;
  border: 1px solid var(--canvas-border-strong);
  border-radius: 20px;
  background: var(--canvas-glass-strong);
  box-shadow: var(--canvas-panel-shadow);
  backdrop-filter: blur(18px);
  pointer-events: auto;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
  grid-template-columns: minmax(128px, 168px) minmax(180px, 1fr) auto;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-row > label {
  min-width: 0;
  gap: 4px;
  color: #667085;
  font-size: 11px;
  font-weight: 850;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-row > label input,
body:not(.auth-required) .layout.canvas-layout .canvas-board-row > label select {
  width: 100%;
  min-height: 32px;
  border-radius: 11px;
  font-size: 13px;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions {
  align-self: end;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 1px;
  scrollbar-width: thin;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions button,
body:not(.auth-required) .layout.canvas-layout .canvas-board-actions .workflow-dirty-badge {
  flex: 0 0 auto;
  min-height: 32px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions button.has-ui-icon {
  width: 34px;
  min-width: 34px;
  padding: 0;
  font-size: 0;
  justify-content: center;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions button.has-ui-icon .ui-icon {
  margin: 0;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions .workflow-dirty-badge {
  max-width: 86px;
  overflow: hidden;
  text-overflow: ellipsis;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-actions #canvasMediaLibraryBtn,
body:not(.auth-required) .layout.canvas-layout .canvas-board-actions #canvasUndoBtn,
body:not(.auth-required) .layout.canvas-layout .canvas-board-actions #canvasRedoBtn {
  display: inline-flex;
}

body:not(.auth-required) .layout.canvas-layout .canvas-side-dock {
  top: 86px;
  left: 18px;
  z-index: 25;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--canvas-border-strong);
  border-radius: 18px;
  background: var(--canvas-glass-strong);
  box-shadow: 0 16px 42px rgba(15, 23, 42, 0.08);
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .layout.canvas-layout .canvas-dock-button {
  width: 40px;
  height: 40px;
  border-radius: 13px;
  background: #f8fbff;
  color: #344054;
  font-size: 0;
}

body:not(.auth-required) .layout.canvas-layout .canvas-dock-button > .ui-icon {
  margin: 0;
}

body:not(.auth-required) .layout.canvas-layout .canvas-dock-button.primary-action {
  background: linear-gradient(135deg, #2f6db7 0%, #2f6db7 100%);
}

body:not(.auth-required) .layout.canvas-layout .canvas-dock-button:hover {
  transform: translateY(-1px);
}

body:not(.auth-required) .layout.canvas-layout .canvas-ai-composer {
  display: none !important;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-stage {
  inset: 0;
  border: 0;
  border-radius: 0;
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--canvas-grid-size-current, 28px) var(--canvas-grid-size-current, 28px);
  background-position: 0 0;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-drop-hint {
  left: 78px;
  bottom: 82px;
  max-width: min(520px, calc(100% - 190px));
  border-color: rgba(203, 213, 225, 0.86);
  background: rgba(255, 255, 255, 0.82);
  color: #667085;
  box-shadow: 0 10px 26px rgba(15, 23, 42, 0.06);
  backdrop-filter: blur(12px);
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 18px;
  z-index: 24;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  width: auto;
  padding: 0;
  border: 0;
  background: transparent;
  pointer-events: none;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row > * {
  pointer-events: auto;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row .file-summary,
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row .workflow-history-actions {
  min-height: 38px;
  border: 1px solid rgba(203, 213, 225, 0.86);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.07);
  backdrop-filter: blur(16px);
  margin: 0 !important;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row .file-summary {
  display: flex;
  align-items: center;
  padding: 0 14px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row .workflow-history-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row .workflow-history-actions button {
  min-height: 30px;
  border-radius: 999px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card {
  border: 1px solid #dde5ee;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: var(--canvas-card-shadow);
  overflow: visible;
  /* 卡片改 flex 列:头部已浮到卡外(绝对定位),卡身作为唯一在流子级 flex:1 撑满卡高——
     空态/表单内容才能在卡内垂直居中/铺满,不再头重脚轻(见 .infinite-card-body 与空态规则)。 */
  display: flex;
  flex-direction: column;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 16px 34px rgba(15, 23, 42, 0.09);
}

body:not(.auth-required) .layout.canvas-layout .infinite-card.selected {
  border-color: rgba(37, 90, 156, 0.68);
  box-shadow: 0 0 0 2px rgba(37, 90, 156, 0.16), 0 16px 34px rgba(15, 23, 42, 0.1);
}

/* 收口:无限画布「所有模块」标题(图标+名字)统一浮在「卡片上方」(画布上、贴着上边沿,bottom:100%)——
   不论媒体类还是表单类(初始模块),标题都不进卡内、不与模块重叠,卡片本身只剩内容。
   强调色、原字号(13px)、原图标(18px),不加投影(深色画布上白投影会糊成白雾)。
   作用域 :not([data-canvas-type="section"]) 排除分区容器(分区回落到自己的灰底标题栏 7216)。
   ⚠媒体类配套:app.part3.js infiniteCanvasMediaCardChromeHeight 返回 0,卡高=图片比例高(头不占卡高)。 */
body:not(.auth-required) .layout.canvas-layout .infinite-card:not([data-canvas-type="section"]) .infinite-card-head {
  position: absolute;
  left: 0;
  right: auto;
  bottom: calc(100% + 3px);
  z-index: 4;
  width: auto;
  max-width: 100%;
  min-height: 0;
  padding: 0 2px;
  background: transparent;
  color: var(--card-accent, #2f6db7);
}
/* 折叠态多结果模块：浮动卡头随内容收缩(width:auto)时按钮贴在标题右边，margin-left:auto 撑不开。
   带「展开/收起」按钮时改铺满整卡宽 → 按钮落到第一张图片的右上角(和展开态第一格右上角一致)。普通模块仍是紧凑浮标题。
   排除 .result-grid-card(展开态)——它的卡头只占第一格宽(--result-cell-w)，别被这条 :has 规则撑成整卡宽把按钮又推到最右。 */
body:not(.auth-required) .layout.canvas-layout .infinite-card:not([data-canvas-type="section"]):not(.result-grid-card) .infinite-card-head:has(.infinite-card-results-toggle) {
  width: 100%;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card:not([data-canvas-type="section"]) .infinite-card-head strong {
  color: var(--card-accent, #2f6db7);
  font-size: 13px;
  font-weight: 900;
}

/* 图标只留 svg 本身(去掉彩色小色块):透明底,描边图标随头部 currentColor 显强调色;大小/位置保持原样(18px) */
body:not(.auth-required) .layout.canvas-layout .infinite-card:not([data-canvas-type="section"]) .infinite-card-badge {
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--card-accent, #2f6db7);
  font-size: 10px;
}

/* 卡片正文只作用于真实卡片直系子节点；浮层编辑器有独立的内容盒模型。 */
body:not(.auth-required) .layout.canvas-layout .infinite-card > .infinite-card-body {
  padding: 9px;
  flex: 1 1 auto;
  min-height: 0;
}

/* 空态卡身:让空态整块撑满卡身高度,内部再垂直+水平居中——卡片较高时空态不再堆在顶部、下方留白。
   仅作用于「只含空态」的卡身(:has),表单/文本卡身不受影响(内容仍从顶部排布)。 */
body:not(.auth-required) .layout.canvas-layout .infinite-card-body:has(> .infinite-card-empty) {
  display: flex;
  flex-direction: column;
  padding: 12px;
}
body:not(.auth-required) .layout.canvas-layout .infinite-card-body > .infinite-card-empty {
  flex: 1 1 auto;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-note,
body:not(.auth-required) .layout.canvas-layout .infinite-card-meta {
  color: #667085;
  line-height: 1.5;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-field {
  grid-template-columns: 66px minmax(0, 1fr);
  gap: 6px;
  min-height: 26px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-body textarea,
body:not(.auth-required) .layout.canvas-layout .infinite-card-body input,
body:not(.auth-required) .layout.canvas-layout .infinite-card-body select {
  border-radius: 9px;
  font-size: 12px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-media-box,
body:not(.auth-required) .layout.canvas-layout .infinite-card-drop-zone {
  border-color: #dbe7f0;
  border-radius: 12px;
  background: #f8fbfd;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-media img,
body:not(.auth-required) .layout.canvas-layout .infinite-card-media video,
body:not(.auth-required) .layout.canvas-layout .infinite-card-media-grid img,
body:not(.auth-required) .layout.canvas-layout .infinite-card-media-grid video {
  border-radius: 10px;
}

/* 导演台(poser)卡和媒体卡/全景卡一样铺满 body：必须放在这条高特异度(0,3,1)规则里，
   否则上面 .canvas-studio-shell .infinite-card-body{padding:9px} 会盖掉低特异度的 poser 内边距归零，留出一圈白边。 */
body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card:is(.media-card, .panorama-view-card, [data-canvas-type="poser"]) .infinite-card-body {
  padding: 0;
  overflow: hidden;
  border-radius: 7px;
  background: transparent;
}

body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card.panorama-view-card .infinite-card-panorama {
  height: 100%;
  min-height: 0;
  border: 0;
  border-radius: 7px;
  box-shadow: none;
}

body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card.media-card .infinite-card-media {
  display: block;
  height: 100%;
  overflow: hidden;
  border-radius: 7px;
  background: transparent;
}

body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card.media-card .infinite-card-media img,
body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card.media-card .infinite-card-media video {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 7px;
  background: transparent;
  object-fit: cover;
}

body:not(.auth-required) :is(.layout.canvas-layout, .canvas-studio-shell) .infinite-card.media-card .infinite-card-media video {
  object-fit: contain;
  background: #070b10;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-link-zone {
  opacity: 0;
  transition: opacity 140ms ease;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card:hover .infinite-card-link-zone,
body:not(.auth-required) .layout.canvas-layout .infinite-card.selected .infinite-card-link-zone,
body:not(.auth-required) .layout.canvas-layout .infinite-card-link-zone:focus-within,
body:not(.auth-required) .layout.canvas-layout .infinite-card-link-zone:has(.infinite-card-link-handle:hover),
body:not(.auth-required) .layout.canvas-layout .infinite-card-link-zone:has(.infinite-card-link-handle.linking) {
  opacity: 1;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-link-handle {
  width: 24px;
  height: 24px;
  border-color: rgba(47, 109, 183, 0.42);
  background: rgba(47, 109, 183, 0.16);
  /* 连接点不要任何光晕/落影——之前那圈柔影也像「圈圈蒙版」罩在按钮上;靠边框+底色辨识即可,保持干净。 */
  box-shadow: none;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-link-handle::before,
body:not(.auth-required) .layout.canvas-layout .infinite-card-link-handle::after {
  /* canvas-layout 连接点底色偏浅，加号用主题蓝才看得清（深底壳用基础白色）。两条杠用 background 上色。 */
  background: #2f6db7;
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-inline-panel {
  border-color: rgba(203, 213, 225, 0.9);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.13);
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .layout.canvas-layout .infinite-card-inline-panel::before {
  border-bottom-color: rgba(255, 255, 255, 0.96);
}

body:not(.auth-required) .layout.canvas-layout .infinite-inline-panel-head {
  border-bottom-color: #e8eef5;
}

body:not(.auth-required) .layout.canvas-layout .infinite-inline-panel-body {
  gap: 9px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-inline-references,
body:not(.auth-required) .layout.canvas-layout .infinite-inline-reference-empty {
  border-radius: 13px;
  background: #f8fbfd;
}

body:not(.auth-required) .layout.canvas-layout .canvas-empty-card {
  width: min(650px, calc(100% - 180px));
  border-color: rgba(203, 213, 225, 0.88);
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 18px 56px rgba(15, 23, 42, 0.1);
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .layout.canvas-layout .canvas-empty-actions button {
  border-radius: 12px;
}

body:not(.auth-required) .layout.canvas-layout .workflow-inspector-head {
  align-items: center;
  padding-bottom: 12px;
  border-bottom: 1px solid #e8eef5;
}

body:not(.auth-required) .layout.canvas-layout .workflow-inspector-head h2 {
  font-size: 15px;
}

body:not(.auth-required) .layout.canvas-layout .workflow-inspector-body {
  gap: 12px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-search {
  display: grid;
  gap: 6px;
  color: #667085;
  font-size: 11px;
  font-weight: 850;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-search input {
  min-height: 34px;
  border-radius: 12px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-layer-head {
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px solid #e8eef5;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-layer-list {
  gap: 7px;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-layer-item {
  min-height: 44px;
  border-color: #dbe7f0;
  border-radius: 13px;
  background: #ffffff;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-layer-item:hover,
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-layer-item.selected {
  border-color: rgba(47, 109, 183, 0.38);
  background: #eaf2fb;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-tip {
  border-color: #dbe7f0;
  border-style: solid;
  border-radius: 14px;
  background: rgba(248, 251, 253, 0.82);
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-property-panel {
  border-radius: 14px;
  background: rgba(248, 251, 253, 0.82);
}

@media (max-width: 1280px) {
  body:not(.auth-required) .layout.canvas-layout .infinite-canvas-shell.canvas-studio-shell {
    grid-template-columns: minmax(0, 1fr) 260px;
  }

  body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
    grid-template-columns: minmax(118px, 150px) minmax(150px, 1fr) auto;
  }
}

@media (max-width: 980px) {
  body:not(.auth-required) .layout.canvas-layout .infinite-canvas-shell.canvas-studio-shell {
    grid-template-columns: 1fr;
  }

  body:not(.auth-required) .layout.canvas-layout .infinite-canvas-inspector {
    display: none;
  }

  body:not(.auth-required) .layout.canvas-layout .infinite-canvas-main {
    border-radius: 20px;
  }

  body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
    left: 12px;
    right: 12px;
    top: 12px;
  }

  body:not(.auth-required) .layout.canvas-layout .canvas-side-dock {
    top: 110px;
    left: 12px;
  }
}

/* Infinite canvas pure-canvas mode: no right inspector, top tool rail instead of left rail. */
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-shell.canvas-studio-shell {
  grid-template-columns: minmax(0, 1fr);
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-inspector {
  display: none !important;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-main {
  border-radius: 20px;
}

body:not(.auth-required) .layout.canvas-layout .canvas-side-dock {
  top: 18px;
  left: 18px;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  padding: 8px;
  border-radius: 20px;
}

body:not(.auth-required) .layout.canvas-layout .canvas-dock-button {
  width: 38px;
  height: 38px;
  border-radius: 12px;
}

body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
  left: 258px;
  right: 18px;
  grid-template-columns: minmax(136px, 180px) minmax(180px, 1fr) auto;
}

body:not(.auth-required) .layout.canvas-layout .infinite-canvas-drop-hint {
  left: 18px;
}

@media (max-width: 1180px) {
  body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
    top: 72px;
    left: 18px;
    grid-template-columns: minmax(130px, 170px) minmax(170px, 1fr) auto;
  }
}

@media (max-width: 760px) {
  body:not(.auth-required) .layout.canvas-layout .canvas-board-row {
    grid-template-columns: 1fr;
  }

  body:not(.auth-required) .layout.canvas-layout .canvas-board-actions {
    grid-column: auto;
  }
}

/* Final studio alignment: workflow uses the infinite-canvas surface and floating controls. */
body:not(.auth-required) .workflow-shell {
  --canvas-surface: var(--studio-canvas-surface-light);
  --canvas-grid-size-current: 28px;
  --canvas-grid-image: var(--studio-canvas-grid-image-light);
  --canvas-grid-line-light: var(--studio-canvas-grid-light);
  --canvas-grid-line-dark: var(--studio-canvas-grid-dark);
  grid-template-columns: minmax(0, 1fr) 286px;
  gap: 0;
  background: linear-gradient(180deg, #f8fafc 0%, #eef2f6 100%);
}

body:not(.auth-required) .layout.workflow-layout .workflow-main {
  position: relative;
  display: block;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body:not(.auth-required) .layout.workflow-layout .workflow-stage-wrap,
body:not(.auth-required) .layout.workflow-layout .workflow-lite-wrap {
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--workflow-grid-size, var(--canvas-grid-size-current, 28px)) var(--workflow-grid-size, var(--canvas-grid-size-current, 28px));
  background-position: var(--workflow-grid-position-x, 0px) var(--workflow-grid-position-y, 0px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-lite-canvas {
  background: transparent;
}

body:not(.auth-required) .layout.workflow-layout .workflow-main > .workflow-stage-wrap.workflow-lite-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar {
  position: absolute;
  z-index: 18;
  top: 18px;
  left: 18px;
  right: 18px;
  display: grid;
  grid-template-columns: minmax(170px, 260px) minmax(260px, 1fr);
  gap: 8px 10px;
  padding: 10px;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar > label {
  display: grid;
  gap: 4px;
  min-width: 0;
  color: #667085;
  font-size: 11px;
  font-weight: 850;
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar > label input {
  min-height: 32px;
  padding: 0 10px;
  border-radius: 11px;
  font-size: 13px;
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 1px 1px 3px;
  scrollbar-width: thin;
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar-actions button,
body:not(.auth-required) .layout.workflow-layout .workflow-toolbar-actions .workflow-dirty-badge {
  flex: 0 0 auto;
  min-height: 31px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease, background 150ms ease;
}

body:not(.auth-required) .layout.workflow-layout .workflow-toolbar-actions button:hover {
  transform: translateY(-1px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-main > .workflow-status-row {
  position: absolute;
  z-index: 18;
  left: 18px;
  bottom: 18px;
  width: auto;
  max-width: min(760px, calc(100% - 36px));
  padding: 7px;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-main > .workflow-status-row .file-summary {
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(248, 251, 253, 0.86);
  white-space: nowrap;
}

body:not(.auth-required) .layout.workflow-layout .workflow-main > .workflow-status-row .workflow-history-actions {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding-left: 4px;
}

body:not(.auth-required) .layout.workflow-layout .workflow-main > .workflow-status-row .workflow-history-actions button {
  min-height: 32px;
  border-radius: 999px;
}

body:not(.auth-required) .layout.workflow-layout .workflow-minimap {
  right: 18px;
  bottom: 86px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 18px 44px rgba(15, 23, 42, 0.11);
  backdrop-filter: blur(14px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-inspector {
  align-self: stretch;
  height: calc(100% - 24px);
  margin: 12px 12px 12px 0;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.86);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .workflow-empty-state {
  border-color: rgba(203, 213, 225, 0.82);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.09);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .layout.canvas-layout .canvas-studio-shell .infinite-canvas-stage,
body:not(.auth-required) .canvas-studio-shell .infinite-canvas-stage {
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--canvas-grid-size-current, 28px) var(--canvas-grid-size-current, 28px);
}

body:not(.auth-required) .canvas-studio-shell .canvas-board-row,
body:not(.auth-required) .canvas-studio-shell .canvas-side-dock,
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row {
  border-color: rgba(213, 220, 229, 0.9);
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card {
  border-color: #dde5ee;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 28px rgba(15, 23, 42, 0.07);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 16px 34px rgba(15, 23, 42, 0.09);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card.selected {
  border-color: rgba(37, 90, 156, 0.68);
  box-shadow: 0 0 0 2px rgba(37, 90, 156, 0.16), 0 16px 34px rgba(15, 23, 42, 0.1);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-head {
  min-height: 34px;
  padding: 7px 9px;
  border-radius: 9px 9px 0 0;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-head strong {
  color: #ffffff;
  font-size: 13px;
  font-weight: 900;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-badge {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  font-size: 12px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-body {
  padding: 9px 10px 10px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-field {
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 7px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-body textarea,
body:not(.auth-required) .canvas-studio-shell .infinite-card-body input,
body:not(.auth-required) .canvas-studio-shell .infinite-card-body select {
  border-radius: 8px;
  font-size: 12px;
}

/* Workflow and infinite canvas share the same studio surface. */
body:not(.auth-required) .workflow-shell {
  --canvas-surface: var(--studio-canvas-surface-light);
  --canvas-grid-size-current: 28px;
  --canvas-grid-image: var(--studio-canvas-grid-image-light);
  --canvas-grid-line-light: var(--studio-canvas-grid-light);
  --canvas-grid-line-dark: var(--studio-canvas-grid-dark);
  grid-template-columns: minmax(0, 1fr) 286px;
  gap: 0;
  background: linear-gradient(180deg, #f8fafc 0%, #eef2f6 100%);
}

body.theme-dark:not(.auth-required) .workflow-shell,
body.theme-dark:not(.auth-required) .layout.workflow-layout .workflow-shell {
  --canvas-surface: var(--studio-canvas-surface-dark);
  --canvas-grid-size-current: 28px;
  --canvas-grid-image: var(--studio-canvas-grid-image-dark);
  background: linear-gradient(180deg, #0e1726 0%, #0b121f 100%);
}

body:not(.auth-required) .workflow-main {
  position: relative;
  display: block;
  min-height: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

body:not(.auth-required) .workflow-stage-wrap,
body:not(.auth-required) .workflow-lite-wrap {
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--workflow-grid-size, var(--canvas-grid-size-current, 28px)) var(--workflow-grid-size, var(--canvas-grid-size-current, 28px));
  background-position: var(--workflow-grid-position-x, 0px) var(--workflow-grid-position-y, 0px);
}

body:not(.auth-required) .workflow-lite-canvas {
  background: transparent;
}

body:not(.auth-required) .workflow-main > .workflow-stage-wrap.workflow-lite-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

body:not(.auth-required) .workflow-toolbar {
  position: absolute;
  z-index: 18;
  top: 18px;
  left: 18px;
  right: 18px;
  display: grid;
  grid-template-columns: minmax(170px, 260px) minmax(260px, 1fr);
  gap: 8px 10px;
  padding: 10px;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(18px);
}

body:not(.auth-required) .workflow-toolbar > label {
  display: grid;
  gap: 4px;
  min-width: 0;
  color: #667085;
  font-size: 11px;
  font-weight: 850;
}

body:not(.auth-required) .workflow-toolbar > label input {
  min-height: 32px;
  padding: 0 10px;
  border-radius: 11px;
  font-size: 13px;
}

body:not(.auth-required) .workflow-toolbar-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 1px 1px 3px;
  scrollbar-width: thin;
}

body:not(.auth-required) .workflow-toolbar-actions button,
body:not(.auth-required) .workflow-toolbar-actions .workflow-dirty-badge {
  flex: 0 0 auto;
  min-height: 31px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: 12px;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease, background 150ms ease;
}

body:not(.auth-required) .workflow-toolbar-actions button:hover {
  transform: translateY(-1px);
}

body:not(.auth-required) .workflow-main > .workflow-status-row {
  position: absolute;
  z-index: 18;
  left: 18px;
  bottom: 18px;
  width: auto;
  max-width: min(760px, calc(100% - 36px));
  padding: 7px;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .workflow-main > .workflow-status-row .file-summary {
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(248, 251, 253, 0.86);
  white-space: nowrap;
}

body:not(.auth-required) .workflow-main > .workflow-status-row .workflow-history-actions {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding-left: 4px;
}

body:not(.auth-required) .workflow-main > .workflow-status-row .workflow-history-actions button {
  min-height: 32px;
  border-radius: 999px;
}

body:not(.auth-required) .workflow-minimap {
  right: 18px;
  bottom: 86px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.82);
  box-shadow: 0 18px 44px rgba(15, 23, 42, 0.11);
  backdrop-filter: blur(14px);
}

body:not(.auth-required) .workflow-inspector {
  align-self: stretch;
  height: calc(100% - 24px);
  margin: 12px 12px 12px 0;
  border: 1px solid rgba(213, 220, 229, 0.9);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.86);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .workflow-empty-state {
  border-color: rgba(203, 213, 225, 0.82);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.09);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .layout.canvas-layout .canvas-studio-shell .infinite-canvas-stage,
body:not(.auth-required) .canvas-studio-shell .infinite-canvas-stage {
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--canvas-grid-size-current, 28px) var(--canvas-grid-size-current, 28px);
}

body:not(.auth-required) .canvas-studio-shell .canvas-board-row,
body:not(.auth-required) .canvas-studio-shell .canvas-side-dock,
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-status-row {
  border-color: rgba(213, 220, 229, 0.9);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
  backdrop-filter: blur(16px);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card {
  border-color: #dde5ee;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 28px rgba(15, 23, 42, 0.07);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 16px 34px rgba(15, 23, 42, 0.09);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card.selected {
  border-color: rgba(37, 90, 156, 0.68);
  box-shadow: 0 0 0 2px rgba(37, 90, 156, 0.16), 0 16px 34px rgba(15, 23, 42, 0.1);
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-head {
  min-height: 34px;
  padding: 7px 9px;
  border-radius: 9px 9px 0 0;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-head strong {
  color: #ffffff;
  font-size: 13px;
  font-weight: 900;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-badge {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  font-size: 12px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-body {
  padding: 9px 10px 10px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-field {
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 7px;
}

body:not(.auth-required) .canvas-studio-shell .infinite-card-body textarea,
body:not(.auth-required) .canvas-studio-shell .infinite-card-body input,
body:not(.auth-required) .canvas-studio-shell .infinite-card-body select {
  border-radius: 8px;
  font-size: 12px;
}

@media (max-width: 1280px) {
  body:not(.auth-required) .workflow-shell {
    grid-template-columns: minmax(0, 1fr) 258px;
  }

  body:not(.auth-required) .workflow-toolbar {
    grid-template-columns: minmax(150px, 220px) minmax(220px, 1fr);
  }
}

@media (max-width: 980px) {
  body:not(.auth-required) .workflow-shell {
    grid-template-columns: 1fr;
  }

  body:not(.auth-required) .workflow-inspector {
    display: none;
  }

  body:not(.auth-required) .workflow-toolbar {
    left: 10px;
    right: 10px;
    grid-template-columns: 1fr;
  }
}

/* 无限画布：项目库、媒体卡片和底部创作栏结构，视觉保持绘流 AI 风格。 */
.canvas-studio-shell {
  --canvas-surface: #f4f7fa;
  --canvas-ink: #101828;
  --canvas-muted: #667085;
  --canvas-line: rgba(184, 197, 214, 0.42);
  --canvas-line-strong: rgba(130, 152, 180, 0.34);
  --canvas-glass: rgba(255, 255, 255, 0.82);
  --canvas-shadow-card: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 28px rgba(15, 23, 42, 0.07);
  --canvas-grid-size-current: 28px;
  --canvas-grid-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M0 .5H28M.5 0V28' fill='none' stroke='%23b8c5d6' stroke-opacity='.42' stroke-width='1'/%3E%3C/svg%3E");
  /* canvas 直绘网格的线色令牌(与上面 SVG 图案同源;暗色取 --studio-canvas-grid-dark 亮度令牌) */
  --canvas-grid-line-light: rgba(184, 197, 214, 0.42);
  --canvas-grid-line-dark: var(--studio-canvas-grid-dark, rgba(255, 255, 255, 0.08));
  background: linear-gradient(180deg, #f8fafc 0%, #eef2f6 100%);
}

body:not(.auth-required) .layout.canvas-layout .canvas-studio-shell .infinite-canvas-stage,
.canvas-studio-shell .infinite-canvas-stage {
  background-color: var(--canvas-surface);
  background-image: var(--canvas-grid-image);
  background-size: var(--canvas-grid-size-current, 28px) var(--canvas-grid-size-current, 28px);
  background-position: 0 0;
}

.canvas-studio-shell .canvas-board-row {
  top: 18px;
  left: 86px;
  width: min(560px, calc(100vw - 620px));
  min-width: 420px;
  grid-template-columns: 150px minmax(180px, 1fr) auto;
  padding: 8px 10px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.82);
  border-color: rgba(213, 220, 229, 0.9);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 10px 24px rgba(15, 23, 42, 0.055);
}

.canvas-studio-shell .canvas-board-actions #canvasSaveBtn,
.canvas-studio-shell .canvas-board-actions #canvasFitBtn {
  display: inline-flex;
}

.canvas-studio-shell .canvas-board-actions #canvasStatus {
  display: inline-flex;
}

.canvas-studio-shell .canvas-side-dock {
  top: 92px;
  left: 18px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 16px 42px rgba(15, 23, 42, 0.08);
}

/* ===== 画布/工作流顶部工具栏：默认展开；拖动顶部手柄上滑收起 / 下滑展开(轻点切换)。桌面+手机端通用 =====
   收起态由 .flow-bar-collapsed (app.js 的 bindFlowToolbarToggle 切换)控制；默认无此类 = 展开 = 现有可见状态。
   桌面布局下工具栏是覆盖在 stage 上的浮动卡片(.canvas-board-row / .workflow-toolbar)，收起=淡出上移；
   移动端工具栏是 in-flow 的 grid 行(见 32261+ 的 body.mobile-ui 布局)，收起=把该行高度压到 0 让画布补满。
   仅登录页(auth-required)不生效。 */

/* 过渡(浮动卡片两端通用)：松手后平滑回弹 */
body:not(.auth-required) .layout.canvas-layout .infinite-canvas-main .canvas-board-row,
body:not(.auth-required) .layout.workflow-layout .workflow-main .workflow-toolbar {
  transition:
    opacity 240ms var(--motion-premium-in),
    transform 280ms var(--motion-premium-in);
  will-change: transform, opacity;
}

/* 拖动跟手时关掉过渡，让工具栏实时跟随手指/指针位移 */
body:not(.auth-required) .infinite-canvas-main.flow-bar-dragging .canvas-board-row,
body:not(.auth-required) .workflow-main.flow-bar-dragging .workflow-toolbar {
  transition: none !important;
}

/* 工具栏文字不可选(输入框除外)：否则在工具栏上滑收起时会选中按钮文字，导致划不动 */
body:not(.auth-required) .layout.canvas-layout .canvas-board-row,
body:not(.auth-required) .layout.workflow-layout .workflow-toolbar {
  -webkit-user-select: none;
  user-select: none;
}
body:not(.auth-required) .layout.canvas-layout .canvas-board-row input,
body:not(.auth-required) .layout.canvas-layout .canvas-board-row textarea,
body:not(.auth-required) .layout.workflow-layout .workflow-toolbar input,
body:not(.auth-required) .layout.workflow-layout .workflow-toolbar textarea {
  -webkit-user-select: text;
  user-select: text;
}
/* 拖动中整块禁用选择(含正在拖的瞬间) */
body:not(.auth-required) .infinite-canvas-main.flow-bar-dragging,
body:not(.auth-required) .infinite-canvas-main.flow-bar-dragging *,
body:not(.auth-required) .workflow-main.flow-bar-dragging,
body:not(.auth-required) .workflow-main.flow-bar-dragging * {
  -webkit-user-select: none !important;
  user-select: none !important;
}

/* 桌面：收起 = 浮动卡片淡出上移、不可点 */
body:not(.mobile-ui):not(.auth-required) .layout.canvas-layout .infinite-canvas-main.flow-bar-collapsed .canvas-board-row,
body:not(.mobile-ui):not(.auth-required) .layout.workflow-layout .workflow-main.flow-bar-collapsed .workflow-toolbar {
  opacity: 0;
  transform: translateY(-18px);
  visibility: hidden;
  pointer-events: none;
}

/* 收起态迷你条：小项目名（左上角）+ 图标快捷按钮 + 展开钮（用户要求：收起后是"简洁的按钮"而非空无一物） */
body:not(.auth-required) .flow-toolbar-mini {
  position: absolute; top: 10px; left: 12px; z-index: 40;
  display: none; align-items: center; gap: 2px;
  padding: 4px 6px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--border);
  /* 阴影收敛(2026-07 用户点名太大):贴面小投影即可,轮廓靠边框 */
  box-shadow: 0 2px 8px rgba(8, 12, 22, .08);
  animation: flowMiniIn .18s ease;
}
@keyframes flowMiniIn { from { opacity: 0; transform: translateY(-6px); } }
body:not(.auth-required) .infinite-canvas-main.flow-bar-collapsed > .flow-toolbar-mini,
body:not(.auth-required) .workflow-main.flow-bar-collapsed > .flow-toolbar-mini { display: inline-flex; }
.flow-mini-name {
  max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: inline-flex; align-items: center; min-height: 30px;
  font-size: 12px; font-weight: 750; color: var(--muted); padding: 0 9px; cursor: text; flex: none;
}
.flow-mini-name:hover { color: var(--text); }
/* 双击改名的原位编辑框:尺寸贴合迷你条,不撑高 */
.flow-mini-name-edit {
  width: 150px; min-height: 30px; height: 30px; padding: 0 6px; margin: 0;
  border: 1px solid var(--accent); border-radius: 6px;
  background: var(--panel, #fff); color: var(--text);
  font-size: 12px; font-weight: 700; outline: none; box-sizing: border-box;
}
.flow-mini-sep { width: 1px; height: 18px; background: var(--border); margin: 0 4px; flex: none; }
.flow-mini-btn {
  width: 30px; height: 30px; display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 9px; background: transparent; color: var(--muted); cursor: pointer; flex: none;
  transition: background .13s ease, color .13s ease;
}
.flow-mini-btn:hover { background: var(--surface-3); color: var(--text); }
/* 危险语义的代理按钮(清空流媒体):悬停给危险色,和展开态的 danger 按钮呼应 */
.flow-mini-btn[data-flow-mini-target="#workflowClearStreamBtn"]:hover { background: var(--danger-soft); color: var(--danger); }
.flow-mini-btn svg {
  width: 17px; height: 17px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.55; stroke-linecap: round; stroke-linejoin: round;
}

/* 移动端：工具栏 = 浮动覆盖卡片(见下方 body.mobile-ui 悬浮规则)，画布始终铺满；收起 = 卡片淡出上移，画布不随收起位移。
   目标元素与桌面(9201)及 app.js 拖动绘制的元素一致：画布=.canvas-board-row，工作流=.workflow-toolbar。 */
body.mobile-ui:not(.auth-required) #appLayout[data-module-panel="canvasModule"] #infiniteCanvasTab.active .infinite-canvas-main.flow-bar-collapsed .canvas-board-row,
body.mobile-ui:not(.auth-required) #appLayout[data-module-panel="workflowModule"] #workflowTab.active .workflow-main.flow-bar-collapsed .workflow-toolbar {
  opacity: 0 !important;
  transform: translateY(-110%) !important;
  visibility: hidden !important;
  pointer-events: none !important;
  transition:
    opacity var(--motion-premium-base) var(--motion-premium-in),
    transform var(--motion-premium-base) var(--motion-premium-in) !important;
}

/* 收起态顶部中央的灰色下拉提示横纹已删(2026-07 用户点名难看):下拉手势仍在(顶边 34px 起手),
   展开入口=迷你条 chevron;别把这条提示横纹加回来。 */

.canvas-studio-shell .canvas-dock-button {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04);
}

.canvas-studio-shell .canvas-dock-button.primary-action {
  background: linear-gradient(135deg, #2f6db7 0%, #2f6db7 100%);
  font-size: 22px;
}

.canvas-studio-shell .canvas-ai-composer {
  top: auto;
  right: auto;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: min(880px, calc(100% - 126px));
  max-width: 880px;
  max-height: min(34vh, 240px);
  grid-template-columns: 190px minmax(260px, 1fr);
  grid-template-rows: auto auto auto;
  gap: 10px 12px;
  padding: 11px;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 18px 56px rgba(15, 23, 42, 0.13);
  overflow: auto;
}

.canvas-studio-shell .canvas-composer-head {
  grid-column: 1 / -1;
  align-items: center;
  padding-bottom: 4px;
  border-bottom: 0;
}

.canvas-studio-shell .canvas-composer-head strong {
  font-size: 15px;
}

.canvas-studio-shell .canvas-composer-head small {
  display: none;
}

.canvas-studio-shell .canvas-composer-ref-drop {
  grid-row: 2 / span 2;
  min-height: 112px;
  border-radius: 16px;
}

.canvas-studio-shell .canvas-prompt-box {
  min-width: 0;
}

.canvas-studio-shell .canvas-prompt-box textarea {
  min-height: 66px;
  border-radius: 14px;
  resize: vertical;
}

.canvas-studio-shell .canvas-generate-options {
  grid-template-columns: 118px minmax(180px, 1fr) repeat(4, minmax(82px, 112px)) 128px;
  gap: 8px;
}

.canvas-studio-shell .canvas-generate-options label {
  min-width: 0;
}

.canvas-studio-shell .canvas-generate-options .primary {
  grid-column: auto;
  min-height: 38px;
}

.canvas-studio-shell .canvas-composer-result {
  grid-column: 2 / -1;
  display: none;
}

.canvas-studio-shell .infinite-canvas-drop-hint {
  left: 86px;
  bottom: 104px;
  background: rgba(255, 255, 255, 0.78);
}

.canvas-studio-shell .canvas-empty-card {
  width: min(680px, calc(100% - 220px));
  border-radius: 28px;
  box-shadow: 0 18px 56px rgba(15, 23, 42, 0.12);
}

.canvas-studio-shell .canvas-empty-card > strong {
  font-size: 22px;
}

.canvas-studio-shell .canvas-empty-actions {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.canvas-studio-shell .canvas-empty-actions button {
  border-radius: 14px;
  background: #eaf2fb;
  color: #2f6db7;
}

.canvas-studio-shell .infinite-card {
  border-color: #dde5ee;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: var(--canvas-shadow-card);
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

.canvas-studio-shell .infinite-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 16px 34px rgba(15, 23, 42, 0.09);
}

.canvas-studio-shell .infinite-card.selected {
  border-color: rgba(37, 90, 156, 0.68);
  box-shadow: 0 0 0 2px rgba(37, 90, 156, 0.16), 0 16px 34px rgba(15, 23, 42, 0.1);
}

.canvas-studio-shell .infinite-card.selected::before {
  content: "";
  position: absolute;
  inset: -4px;
  z-index: -1;
  border: 1px solid rgba(37, 90, 156, 0.34);
  border-radius: calc(var(--radius, 10px) + 5px);
  background: transparent;
  box-shadow: 0 0 0 4px rgba(37, 90, 156, 0.06);
  pointer-events: none;
  animation: none;
}

.canvas-studio-shell .infinite-card.running {
  border-color: #0ea5e9;
  box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.24), 0 24px 54px rgba(14, 165, 233, 0.2);
}

.canvas-studio-shell .infinite-card.running .infinite-card-head {
  background-image: linear-gradient(90deg, rgba(14, 165, 233, 0.06), rgba(14, 165, 233, 0.12), rgba(14, 165, 233, 0.06));
  background-size: 100% 100%;
  animation: none;
}

@keyframes infiniteCanvasSelectedPulse {
  0%, 100% {
    opacity: 0.74;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.01);
  }
}

@keyframes infiniteCanvasHeadSweep {
  from {
    background-position: 180% 0;
  }
  to {
    background-position: -180% 0;
  }
}

.canvas-studio-shell .infinite-card-head {
  min-height: 34px;
  padding: 7px 9px;
  border-radius: 9px 9px 0 0;
}

.canvas-studio-shell .infinite-card-badge {
  width: 20px;
  height: 20px;
  border-radius: 7px;
}

.canvas-studio-shell .infinite-card-link-handle {
  width: 22px;
  height: 22px;
  flex-basis: 22px;
  cursor: crosshair;
}

.canvas-studio-shell .infinite-card-link-zone {
  top: 50%;
  bottom: auto;
}

.canvas-studio-shell .infinite-card-body {
  padding: 10px;
}

.canvas-studio-shell .infinite-card[data-canvas-type="media"] {
  border-radius: 14px;
}

.canvas-studio-shell .infinite-card[data-canvas-type="media"] .infinite-card-head {
  background: linear-gradient(135deg, #2f6db7 0%, #255a9c 100%);
}

.canvas-studio-shell .infinite-card-media img,
.canvas-studio-shell .infinite-card-media video {
  display: block;
  width: 100%;
  height: auto;
  max-height: 460px;
  border: 0;
  border-radius: 14px;
  object-fit: contain;
  background: #f7fafc;
}

.canvas-studio-shell .infinite-card-media-box {
  min-height: 172px;
  border-radius: 16px;
  background: rgba(248, 251, 253, 0.92);
}

.canvas-studio-shell .infinite-card-media-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.canvas-studio-shell .infinite-card-media-grid button {
  min-height: 82px;
  border-radius: 12px;
  transition: transform 0.12s ease, border-color 0.12s ease;
}

.canvas-studio-shell .infinite-card-media-grid button:hover {
  transform: translateY(-1px);
  border-color: rgba(47, 109, 183, 0.42);
}

.canvas-studio-shell .infinite-card-media-grid img,
.canvas-studio-shell .infinite-card-media-grid video {
  height: 82px;
  max-height: 82px;
}

.canvas-studio-shell .infinite-card.result-grid-card,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card {
  border-color: transparent !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: 0 !important;
  overflow: visible !important;
}

.canvas-studio-shell .infinite-card.result-grid-card:hover,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card:hover {
  transform: none;
  box-shadow: none !important;
}

.canvas-studio-shell .infinite-card.result-grid-card.selected,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card.selected {
  border-color: transparent !important;
  box-shadow: none !important;
}

.canvas-studio-shell .infinite-card.result-grid-card.selected::before {
  display: none;
}

.canvas-studio-shell .infinite-card.result-grid-card > .infinite-card-head,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card > .infinite-card-head,
body:not(.auth-required) .layout.canvas-layout .infinite-card.result-grid-card > .infinite-card-head {
  position: absolute;
  z-index: 8;
  top: -38px;
  bottom: auto;
  left: 0;
  right: auto;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  width: var(--result-cell-w, calc((100% - var(--result-col-gap, 18px)) * 0.5)); /* 只占第一格宽 → 收起按钮落在「第一张图片」右上角 */
  max-width: none;
  min-height: 32px;
  height: 32px;
  padding: 0;
  border-radius: 12px;
  background: transparent;
  pointer-events: none;
}

.canvas-studio-shell .infinite-card.result-grid-card > .infinite-card-head > :not(.infinite-card-results-toggle) {
  display: none;
}

.canvas-studio-shell .infinite-card.result-grid-card .infinite-card-results-toggle,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card .infinite-card-results-toggle {
  /* 只让浮起的药丸可点；尺寸/描边/阴影一律沿用折叠态基础样式，保证展开=收起长一个样。 */
  pointer-events: auto;
}

.canvas-studio-shell .infinite-card.result-grid-card > .infinite-card-body,
body:not(.auth-required) .canvas-studio-shell .infinite-card.result-grid-card > .infinite-card-body {
  padding: 0 !important;
  overflow: visible !important;
  background: transparent !important;
}

.canvas-studio-shell .infinite-card-drop-zone {
  min-height: 150px;
  border-radius: 14px;
}

.canvas-studio-shell .infinite-card-field {
  grid-template-columns: 68px minmax(0, 1fr);
}

.canvas-studio-shell .infinite-card-body textarea,
.canvas-studio-shell .infinite-card-body input,
.canvas-studio-shell .infinite-card-body select {
  border-radius: 10px;
}

.canvas-studio-shell .infinite-canvas-link {
  stroke: var(--wire-fx-line, #6f91b8);
  stroke-width: calc(2.6px * var(--canvas-link-zoom, 1));
}

.canvas-studio-shell .infinite-canvas-link-hit {
  stroke-width: 24;
}

.canvas-studio-shell .infinite-canvas-link:hover,
.canvas-studio-shell .infinite-canvas-link.hovered,
.canvas-studio-shell .infinite-canvas-link.selected,
.canvas-studio-shell .infinite-canvas-link.energized {
  stroke: var(--wire-fx-line-selected, #3478a6);
  stroke-width: calc(2.75px * var(--canvas-link-zoom, 1));
}

.canvas-studio-shell .infinite-canvas-status-row {
  left: 18px;
  bottom: 18px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu {
  min-width: 300px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: 0 18px 48px rgba(15, 23, 42, 0.16);
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu {
  width: 188px;
  min-width: 188px;
  max-width: 188px;
  padding: 6px;
  border-radius: 14px;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.13);
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu button {
  min-height: 34px;
  padding: 7px 8px;
  gap: 8px;
  border-radius: 10px;
  font-size: 12px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-menu-heading {
  margin: 2px 2px 4px;
  padding: 5px 5px 6px;
  font-size: 12px;
  min-width: 0;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-menu-heading > span:last-child,
body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-title-line > span:first-child,
body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-description {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-menu-heading > span:last-child {
  display: block;
  min-width: 0;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-label {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-copy {
  min-width: 0;
  overflow: hidden;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-title-line {
  display: block;
  min-width: 0;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-title-line > span:first-child {
  display: block;
  max-width: 112px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-description {
  max-width: 112px;
  font-size: 10.5px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-color-badge {
  width: 22px;
  height: 22px;
  flex-basis: 22px;
  border-radius: 7px;
  font-size: 11px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-icon {
  width: 22px;
  height: 22px;
  flex-basis: 22px;
  border-radius: 7px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .context-icon svg {
  width: 13px;
  height: 13px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu.canvas-item-menu .shortcut-hint {
  font-size: 11px;
}

body:not(.auth-required) .context-menu.canvas-item-menu {
  width: 188px !important;
  min-width: 188px !important;
  max-width: 188px !important;
}

body:not(.auth-required) .context-menu.canvas-item-menu .context-title-line > span:first-child,
body:not(.auth-required) .context-menu.canvas-item-menu .context-description {
  max-width: 112px !important;
}

body:not(.auth-required) .context-menu.canvas-item-menu .context-menu-heading > span:last-child {
  display: -webkit-box !important;
  max-width: 112px !important;
  max-height: 2.6em;
  overflow: hidden;
  white-space: normal !important;
  line-height: 1.3;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

body:not(.auth-required) .context-menu.canvas-add-menu {
  min-width: 280px;
  max-width: 310px;
  padding: 7px;
  border-color: rgba(203, 213, 225, 0.88);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 18px 44px rgba(15, 23, 42, 0.15);
}

body:not(.auth-required) .context-menu.canvas-add-menu button {
  min-height: 34px;
  padding: 6px 8px;
  border-radius: 10px;
  font-size: 12px;
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-menu-heading {
  margin: 6px 4px 4px;
  padding: 0 2px;
  border-bottom: 0;
  color: #667085;
  font-size: 12px;
  font-weight: 860;
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-menu-heading:first-child {
  margin-top: 2px;
  color: #344054;
  font-size: 14px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu button.module-create {
  min-height: 42px;
  margin: 3px 0;
  border: 1px solid #dfe8f2;
  border-left: 4px solid var(--menu-accent, #2f6db7);
  border-radius: 12px !important;
  background: #ffffff;
}

body:not(.auth-required) .context-menu.canvas-add-menu button.module-create {
  min-height: 43px;
  margin: 2px 0;
  padding: 6px 8px;
  border-left-width: 4px;
  border-radius: 13px !important;
  background: rgba(248, 251, 253, 0.92);
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-color-badge {
  width: 26px;
  height: 26px;
  flex-basis: 26px;
  border-radius: 8px;
  font-size: 12px;
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-label {
  gap: 9px;
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-title-line {
  font-size: 12px;
}

body:not(.auth-required) .context-menu.canvas-add-menu .context-description {
  font-size: 10.5px;
  line-height: 1.15;
}

body:not(.auth-required) .context-menu.canvas-add-menu .shortcut-hint {
  font-size: 11px;
}

body:not(.auth-required) .layout.canvas-layout .context-menu button.module-create:hover {
  background: color-mix(in srgb, var(--menu-accent, #2f6db7) 9%, #ffffff);
}

@media (max-width: 1300px) {
  .canvas-studio-shell .canvas-board-row {
    width: min(520px, calc(100vw - 160px));
  }

  .canvas-studio-shell .canvas-ai-composer {
    width: calc(100% - 112px);
    grid-template-columns: 190px minmax(240px, 1fr);
  }

  .canvas-studio-shell .canvas-generate-options {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .canvas-studio-shell .canvas-generate-options .primary {
    grid-column: 1 / -1;
  }
}

@media (max-width: 980px) {
  .canvas-studio-shell .canvas-board-row {
    left: 70px;
    right: 10px;
    width: auto;
    min-width: 0;
  }

  .canvas-studio-shell .canvas-ai-composer {
    left: 70px;
    right: 10px;
    bottom: 64px;
    width: auto;
    transform: none;
    grid-template-columns: 1fr;
  }

  .canvas-studio-shell .canvas-composer-ref-drop,
  .canvas-studio-shell .canvas-composer-result {
    grid-column: 1 / -1;
    grid-row: auto;
  }

  .canvas-studio-shell .canvas-generate-options {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.canvas-studio-shell .canvas-ai-composer {
  grid-template-columns: 180px minmax(260px, 1fr);
  grid-template-rows: auto auto;
  max-height: none;
  overflow: visible;
}

.canvas-studio-shell .canvas-ai-composer {
  display: none !important;
}

.canvas-studio-shell .canvas-composer-head {
  display: none;
}

.canvas-studio-shell .canvas-composer-ref-drop {
  grid-column: 1;
  grid-row: 1 / span 2;
  min-height: 136px;
}

.canvas-studio-shell .canvas-prompt-box {
  grid-column: 2;
  grid-row: 1;
}

.canvas-studio-shell .canvas-prompt-box textarea {
  min-height: 62px;
}

.canvas-studio-shell .canvas-generate-options {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  align-items: end;
}

.canvas-studio-shell .canvas-generate-options label {
  flex: 1 1 88px;
}

.canvas-studio-shell .canvas-generate-options label:has(#canvasGenerateModel) {
  flex-basis: 180px;
}

.canvas-studio-shell .canvas-generate-options label:has(#canvasGenerateCount),
.canvas-studio-shell .canvas-generate-options label:has(#canvasGenerateDuration) {
  flex: 0 0 78px;
}

.canvas-studio-shell .canvas-generate-options .primary {
  flex: 0 0 122px;
  min-height: 36px;
}

@media (max-width: 1300px) {
  .canvas-studio-shell .canvas-ai-composer {
    grid-template-columns: 170px minmax(250px, 1fr);
  }

  .canvas-studio-shell .canvas-generate-options {
    display: flex;
    grid-template-columns: none;
  }

  .canvas-studio-shell .canvas-generate-options .primary {
    grid-column: auto;
  }
}

.workflow-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  height: 100%;
  min-height: 0;
  /* 内层不再当卡片(外观交给最外面的 workbench 卡片)，只透明填充 */
  border: 0;
  border-radius: 0;
  overflow: hidden;
}

.workflow-sidebar,
.workflow-inspector {
  min-height: 0;
  padding: 14px;
  background: #fbfcfe;
  overflow: auto;
}

.workflow-sidebar {
  display: none;
}

.workflow-inspector {
  border-left: 1px solid var(--border);
}

.workflow-head,
.workflow-inspector-head,
.workflow-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.workflow-head p {
  margin-top: 4px;
  color: var(--muted);
  line-height: 1.45;
}

.workflow-select-label,
.workflow-library-filter {
  margin-top: 14px;
}

.workflow-actions,
.workflow-library-filter {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.workflow-library-filter {
  grid-template-columns: 1fr 110px;
}

.workflow-module-library {
  display: grid;
  gap: 10px;
  margin-top: 12px;
  max-height: calc(100vh - 420px);
  overflow: auto;
  padding-right: 4px;
}

.workflow-module-card {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 10px;
  align-items: start;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
  padding: 10px;
  cursor: grab;
  text-align: left;
}

.workflow-module-card:hover {
  border-color: #8fb8d8;
  box-shadow: 0 6px 18px rgba(28, 52, 84, 0.08);
}

.workflow-module-icon {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: #e8f3ee;
  color: var(--accent-strong);
  font-weight: 800;
}

.workflow-module-card[data-category="参数模块"] .workflow-module-icon,
.command-palette-item[data-category="参数模块"] .workflow-module-icon,
.workflow-node[data-category="参数模块"] .workflow-node-type {
  background: #e9f1fb;
  color: #245a9a;
}

.workflow-module-card[data-category="工具模块"] .workflow-module-icon,
.command-palette-item[data-category="工具模块"] .workflow-module-icon,
.workflow-node[data-category="工具模块"] .workflow-node-type {
  background: #f0e9ff;
  color: #6b3fd4;
}

.workflow-module-card[data-category="工作模块"] .workflow-module-icon,
.command-palette-item[data-category="工作模块"] .workflow-module-icon,
.workflow-node[data-category="工作模块"] .workflow-node-type {
  background: #eaf7ed;
  color: #1f7a4d;
}

.workflow-module-card[data-category="输出模块"] .workflow-module-icon,
.command-palette-item[data-category="输出模块"] .workflow-module-icon,
.workflow-node[data-category="输出模块"] .workflow-node-type {
  background: #fff4df;
  color: #995f00;
}

.workflow-module-card[data-category="通用模块"] .workflow-module-icon,
.command-palette-item[data-category="通用模块"] .workflow-module-icon,
.workflow-node[data-category="通用模块"] .workflow-node-type {
  background: #f2f4f7;
  color: #475467;
}

.workflow-module-title {
  font-weight: 760;
}

.workflow-module-desc {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
  margin-top: 3px;
}

.workflow-main {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  position: relative;
  height: 100%;
  min-height: 0;
  min-width: 0;
}

.workflow-toolbar {
  display: grid;
  grid-template-columns: minmax(180px, 0.85fr) minmax(240px, 1.15fr);
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  background: #ffffff;
}

.workflow-toolbar-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: end;
  justify-content: flex-start;
  gap: 8px;
  flex-wrap: wrap;
}

.workflow-dirty-badge {
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0 10px;
  background: #f8fafc;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
}

.workflow-menu-drag-ghost {
  position: fixed;
  z-index: var(--z-drag-ghost);
  display: inline-grid;
  grid-template-columns: 24px minmax(0, auto);
  align-items: center;
  gap: 8px;
  max-width: 220px;
  padding: 7px 10px;
  border: 1px solid color-mix(in srgb, var(--menu-accent, #2f6db7) 28%, #dbe5f0);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.96);
  color: #172033;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.14);
  font-size: 13px;
  font-weight: 760;
  pointer-events: none;
  transform: translate3d(0, 0, 0);
}

.workflow-menu-drag-badge {
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--menu-accent, #2f6db7);
  color: #ffffff;
  font-size: 12px;
  font-weight: 850;
}

.workflow-stage-wrap.workflow-lite-wrap.workflow-menu-drop-ready {
  outline: 2px solid rgba(47, 109, 183, 0.38);
  outline-offset: -2px;
}

.workflow-dirty-badge.dirty {
  border-color: #f2c58c;
  background: #fff7ed;
  color: #9a5b00;
}

.workflow-dirty-badge.clean {
  border-color: #b9cfe8;
  background: #eaf2fb;
  color: #2563a7;
}

.workflow-stage-wrap {
  position: relative;
  min-height: 0;
  overflow: auto;
  touch-action: none;
  overscroll-behavior: none;
  background-color: var(--canvas-surface, var(--studio-canvas-surface-light, #f4f7fa));
  background-image: var(--canvas-grid-image, var(--studio-canvas-grid-image-light));
  background-size: var(--workflow-grid-size, var(--canvas-grid-size-current, 28px)) var(--workflow-grid-size, var(--canvas-grid-size-current, 28px));
  background-position: var(--workflow-grid-position-x, 0px) var(--workflow-grid-position-y, 0px);
}

.workflow-lite-wrap {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  background-color: var(--canvas-surface, var(--studio-canvas-surface-light, #f4f7fa));
  background-image: var(--canvas-grid-image, var(--studio-canvas-grid-image-light));
  background-size: var(--workflow-grid-size, var(--canvas-grid-size-current, 28px)) var(--workflow-grid-size, var(--canvas-grid-size-current, 28px));
  background-position: var(--workflow-grid-position-x, 0px) var(--workflow-grid-position-y, 0px);
}

body:not(.auth-required) .layout.workflow-layout .workflow-stage-wrap.workflow-grid-layer-ready,
body:not(.auth-required) .layout.workflow-layout .workflow-lite-wrap.workflow-grid-layer-ready,
body:not(.auth-required) .workflow-stage-wrap.workflow-grid-layer-ready,
body:not(.auth-required) .workflow-lite-wrap.workflow-grid-layer-ready,
.workflow-stage-wrap.workflow-grid-layer-ready,
.workflow-lite-wrap.workflow-grid-layer-ready {
  background-image: none;
}

.workflow-canvas-grid {
  position: absolute;
  inset: -256px;
  z-index: 0;
  pointer-events: none;
  background-image: var(--canvas-grid-image, var(--studio-canvas-grid-image-light));
  background-size: var(--workflow-grid-size, var(--canvas-grid-size-current, 28px)) var(--workflow-grid-size, var(--canvas-grid-size-current, 28px));
  background-position: var(--workflow-grid-position-x, 0px) var(--workflow-grid-position-y, 0px);
  transform-origin: 256px 256px;
}

.workflow-lite-wrap.workflow-template-drop-target::after {
  content: "松开后添加完整工作流";
  position: absolute;
  inset: 14px;
  z-index: 5;
  display: grid;
  place-items: center;
  border: 2px dashed rgba(47, 109, 183, 0.55);
  border-radius: 18px;
  background: rgba(244, 249, 255, 0.72);
  backdrop-filter: blur(3px);
  color: #255a9c;
  font-size: 16px;
  font-weight: 800;
  pointer-events: none;
}

.workflow-lite-canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  display: block;
  flex: none;
  outline: none;
  touch-action: none;
  cursor: default !important;
  z-index: 1;
  background: transparent;
}

.workflow-lite-canvas:active {
  cursor: default !important;
}

/* 工作流视口事务：canvas、组框、媒体热区共用 compositor transform；选中线动画是屏幕坐标 SVG，
   缩放期只标记失效并隐藏，终绘后同步重算，避免旧 path 被二次 transform。 */
/* 交互期只有位图画布本身会被整层 transform 凑合。
   媒体覆盖层不在此列:它自己的世界层按 ds 精确跟手(will-change 也挂在世界层上),
   给外层再加合成提示只是白占一层显存。 */
.workflow-lite-wrap.workflow-viewport-interacting > .workflow-lite-canvas {
  transform-origin: 0 0;
  backface-visibility: hidden;
  will-change: transform;
}

.workflow-lite-wrap.workflow-viewport-interacting > :is(
  .workflow-media-overlay,
  .workflow-selected-wire-fx
) {
  pointer-events: none !important;
}

/* 选中线覆盖层只有视口大小，平移它会连裁剪窗口一起移动；交互期由 overscan canvas 显示同一连线，
   辅助层隐藏，终绘后按新视口一次恢复。
   ⚠️ 媒体覆盖层**不再**参加这条:它内部已改成「世界层 + transform 跟手」(见 syncWorkflowMediaOverlayViewport),
   平移缩放全程精确对位;而且生成模块结果区现在渲染的是**真实可见的图片/视频**,交互期一藏就等于
   「一拖动结果就消失」,一停更就等于「结果飘在画布上」——两个都是用户报过的 bug,别再加回来。 */
.workflow-lite-wrap.workflow-viewport-interacting > .workflow-selected-wire-fx {
  visibility: hidden !important;
}

/* group layer 只承载绝对定位的 live frame；视口交互期放开自身裁剪，由最外层 stage/wrap 裁剪。 */
.workflow-lite-wrap.workflow-viewport-interacting > .workflow-group-layer,
.infinite-canvas-stage.canvas-interacting > .infinite-canvas-group-layer {
  overflow: visible;
}

.workflow-lite-wrap.workflow-viewport-interacting ~ .workflow-selection-overlay .canvas-selection-toolbar {
  visibility: hidden !important;
  pointer-events: none !important;
}

.workflow-lite-wrap.workflow-viewport-interacting .infinite-canvas-link-pulse {
  animation-play-state: paused !important;
}

/* 节点移动期间节点/连线由 canvas 精确跟手；流光 SVG 和多选工具条若继续显示会停在上一帧位置并制造"拖影"。
   媒体覆盖层同样不参加隐藏(理由见上):它的每个节点层每帧按 node.pos 写 transform，跟手且不留影；
   只在交互期关掉命中，免得透明热区抢走画布手势。 */
.workflow-lite-wrap.workflow-node-interacting > .workflow-selected-wire-fx {
  visibility: hidden !important;
  pointer-events: none !important;
}

.workflow-lite-wrap.workflow-node-interacting > .workflow-media-overlay {
  pointer-events: none !important;
}

.workflow-lite-wrap.workflow-node-interacting ~ .workflow-selection-overlay .canvas-selection-toolbar {
  visibility: hidden !important;
  pointer-events: none !important;
}

.workflow-media-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}

/* 世界层:内部一切都按**画布坐标**排,视口的平移/缩放只作用在这一个元素上。
   于是「跟手」= 每帧一次 transform 写入,不需要重排、不需要重建、也不需要交互期停更。 */
.workflow-media-overlay-world {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  will-change: transform;
}

/* 每个节点一层:节点自己移动时只改这一层的 transform,内部 zone/thumb 的坐标恒为节点局部坐标。 */
.workflow-media-overlay-node {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
}

/* 选中模块的连线流光「独立 SVG 覆盖层」:path 复用无限画布 .infinite-canvas-link-pulse/-glow(单一样式源,同色/同节奏/同 --wire-fx-*)。
   z-index 1 = 在连线(canvas z0)之上、媒体热区(z2)之下;pointer-events:none 纯装饰不挡交互;contain:strict 隔离重绘。
   line 宽经 svg 上注入的 --canvas-link-zoom 随缩放变(见 renderWorkflowSelectedWireFxOverlay),与画布连线一致。 */
.workflow-selected-wire-fx {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

.workflow-selected-wire-fx:not(.is-active) {
  display: none;
}

.workflow-selected-wire-fx.is-viewport-stale {
  display: none !important;
}

/* 覆盖层里所有 path 都不拦交互(base 复用的 .infinite-canvas-link 自带 pointer-events:stroke,这里统一压掉,否则会挡画布)。 */
.workflow-selected-wire-fx path {
  pointer-events: none;
}

/* 工作流覆盖层同样保持细线,只稍微放大流光层以抵消网格背景干扰。 */
.workflow-selected-wire-fx .infinite-canvas-link.energized {
  stroke-width: calc(2.9px * var(--canvas-link-zoom, 1));
}
.workflow-selected-wire-fx .infinite-canvas-link-pulse-veil {
  stroke-width: calc(7.45px * var(--canvas-link-zoom, 1));
  opacity: 0.32;
}
.workflow-selected-wire-fx .infinite-canvas-link-pulse-glow {
  stroke-width: calc(4.4px * var(--canvas-link-zoom, 1));
  opacity: 0.62;
}
.workflow-selected-wire-fx .infinite-canvas-link-pulse-silk {
  stroke-width: calc(2.45px * var(--canvas-link-zoom, 1));
  opacity: 0.94;
}
.workflow-selected-wire-fx .infinite-canvas-link-pulse {
  stroke-width: calc(1.28px * var(--canvas-link-zoom, 1));
  opacity: 1;
}

/* 运行可视化:媒体在节点间「飞行」的缩略图(挂在 #workflowRunFxLayer) */
.workflow-fx-fly {
  position: absolute;
  border-radius: 10px;
  background-size: cover;
  background-position: center;
  background-color: #dbe7f5;
  box-shadow: 0 8px 22px rgba(14, 165, 233, 0.45), 0 0 0 2px rgba(14, 165, 233, 0.85);
  opacity: 0;
  transform: scale(0.7);
  transition: transform 220ms ease, opacity 220ms ease;
  /* 飞行已改 transform 过渡(JS 内联 translate3d);left/top 不可合成,写进 will-change 只浪费图层提示 */
  will-change: transform, opacity;
}
.workflow-fx-fly.is-flying {
  opacity: 1;
  transform: scale(1);
}
.workflow-fx-fly-icon {
  background: linear-gradient(135deg, #0ea5e9, #2f6db7);
}
.workflow-fx-fly-icon::after {
  content: "♪";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 22px;
}

.workflow-media-overlay-zone {
  position: absolute;
  display: block;
  box-sizing: border-box;
  padding: 0;
  border: 0;
  outline: 1px solid transparent;
  outline-offset: -1px;
  border-radius: 8px;
  pointer-events: none;
}

.workflow-media-overlay-zone.drag-over {
  outline-color: #2f6db7;
  background: rgba(47, 109, 183, 0.08);
}

.workflow-media-overlay-empty-hit {
  position: absolute;
  inset: 0;
  pointer-events: auto;
}

.workflow-media-overlay-download-hit {
  position: absolute;
  z-index: 4;
  display: block;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  appearance: none;
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.workflow-media-overlay-download-hit:focus-visible {
  outline: 2px solid #2f6db7;
  outline-offset: 1px;
}

.workflow-media-overlay-thumb {
  position: relative;
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  cursor: grab;
  pointer-events: auto;
  touch-action: manipulation;
}

.workflow-media-overlay-thumb:active {
  cursor: grabbing;
}

.workflow-media-overlay-thumb:hover {
  border-color: rgba(47, 109, 183, 0.45);
  background: rgba(47, 109, 183, 0.04);
}

.workflow-media-overlay-thumb.is-media-ingress {
  cursor: default;
  border-color: transparent;
}

.workflow-media-ingress-overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: inherit;
  color: #fff;
  background: rgba(47, 109, 183, 0.42);
  pointer-events: none;
}

.workflow-media-ingress-overlay::before {
  width: 42%;
  min-width: 14px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(#fff calc(var(--workflow-ingress-progress, 0) * 1turn), rgba(255, 255, 255, 0.38) 0);
  content: "";
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 0);
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 0);
}

.workflow-media-ingress-overlay > span {
  position: absolute;
  font-size: clamp(8px, 0.68em, 11px);
  font-weight: 800;
  line-height: 1;
}

.workflow-media-ingress-overlay:is(.is-queued, .is-checking)::before {
  background: conic-gradient(from 0deg, transparent 0 18%, #fff 18% 72%, transparent 72% 100%);
  animation: workflow-media-ingress-spin 0.9s linear infinite;
}

.workflow-media-ingress-overlay.is-error {
  background: rgba(180, 35, 24, 0.42);
  pointer-events: none;
}

@keyframes workflow-media-ingress-spin {
  to { transform: rotate(1turn); }
}

@media (prefers-reduced-motion: reduce) {
  .workflow-media-ingress-overlay:is(.is-queued, .is-checking)::before { animation: none; }
}

/* 视频格子里的真实播放器:铺满格子、不吃指针(长按拖拽/排序照旧走热区),
   播放控件由 attachSiteVideoPlayerChrome 追加进同一个格子,自己有 pointer-events。
   ⚠️ video 必须 pointer-events:none —— 它盖住整个热区,不让穿透就再也拖不动这块媒体了。 */
.workflow-media-overlay-thumb.has-video-player > video[data-canvas-video-player] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  display: block;
  background: transparent;
  pointer-events: none;
}

.workflow-media-overlay-thumb.has-video-player > .infinite-card-video-controls {
  pointer-events: auto;
}

.workflow-media-overlay-drag-ghost {
  position: fixed;
  z-index: var(--z-drag-ghost);
  width: 56px;
  height: 56px;
  overflow: hidden;
  border: 1px solid #2f6db7;
  border-radius: 8px;
  background: #f7fafd;
  box-shadow: 0 10px 24px rgba(20, 31, 48, 0.14);
  opacity: 0.8; /* 略透,拖动排序时下方的媒体库缩略图能透出来,不被幽灵完全盖住 */
  pointer-events: none;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  color: var(--accent-strong);
  font-size: 12px;
  font-weight: 800;
}

.workflow-media-overlay-drag-ghost img,
.workflow-media-overlay-drag-ghost video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.workflow-media-overlay-drag-ghost.is-blank-stream {
  gap: 4px;
  border-color: rgba(47, 109, 183, 0.45);
  background: linear-gradient(180deg, #f8fbff 0%, #eaf3ff 100%);
  color: #215f9d;
  font-size: 11px;
  line-height: 1;
}

.workflow-blank-stream-glyph {
  display: grid;
  width: 24px;
  height: 24px;
  place-items: center;
  border: 1px solid rgba(47, 109, 183, 0.24);
  border-radius: 999px;
  background: #ffffff;
  color: #2f6db7;
  font-size: 18px;
  font-weight: 850;
}

.legacy-workflow-stage[hidden] {
  display: none;
}

.workflow-stage {
  position: relative;
  width: 2200px;
  height: 1400px;
  transform-origin: 0 0;
  text-rendering: geometricPrecision;
}

.workflow-edges,
.workflow-nodes {
  position: absolute;
  inset: 0;
}

.workflow-edges {
  pointer-events: none;
  overflow: visible;
}

.workflow-edge-path {
  fill: none;
  stroke: #62748e;
  stroke-width: 3;
}

.workflow-edge-path.selected {
  stroke: var(--accent);
  stroke-width: 4;
}

.workflow-nodes {
  pointer-events: none;
}

.workflow-node {
  position: absolute;
  width: 230px;
  min-height: 116px;
  border: 1px solid #d8e1ec;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 10px 24px rgba(20, 31, 48, 0.12);
  overflow: hidden;
  pointer-events: auto;
  user-select: none;
  -webkit-font-smoothing: antialiased;
  backface-visibility: hidden;
}

.workflow-node.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.2), 0 14px 30px rgba(20, 31, 48, 0.18);
}

.workflow-node.disabled {
  border-style: dashed;
  opacity: 0.7;
  box-shadow: none;
}

.workflow-node-header {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 9px 11px;
  background: var(--accent);
  color: #ffffff;
  cursor: move;
}

.workflow-node[data-category="参数模块"] .workflow-node-header {
  background: #2f67b2;
}

.workflow-node[data-category="工具模块"] .workflow-node-header {
  background: #7f56d9;
}

.workflow-node[data-category="工作模块"] .workflow-node-header {
  background: var(--accent);
}

.workflow-node[data-category="输出模块"] .workflow-node-header {
  background: #b54708;
}

.workflow-node[data-category="通用模块"] .workflow-node-header {
  background: #667085;
}

.workflow-node.disabled .workflow-node-header {
  background: #98a2b3;
}

.workflow-node-title {
  font-weight: 800;
  color: #ffffff;
  font-size: 14px;
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.workflow-node-badges {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 5px;
  min-width: 0;
}

.workflow-node-state {
  border-radius: 999px;
  padding: 3px 6px;
  font-size: 12px;
  background: rgba(255, 255, 255, 0.18);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.24);
  white-space: nowrap;
}

.workflow-node-type {
  border-radius: 999px;
  padding: 3px 7px;
  font-size: 12px;
  background: rgba(255, 255, 255, 0.18);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.24);
  white-space: nowrap;
}

.workflow-node .workflow-node-header .workflow-node-type,
.workflow-node .workflow-node-header .workflow-node-state {
  background: rgba(255, 255, 255, 0.18);
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.24);
}

.workflow-node-body {
  display: grid;
  gap: 8px;
  padding: 10px 11px 11px;
  background: #ffffff;
}

.workflow-node.disabled .workflow-node-body {
  background: #f8fafc;
}

.workflow-node-summary {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
  max-height: 38px;
  overflow: hidden;
}

.workflow-port-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.workflow-port-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.workflow-port {
  border: 1px solid #d5dee9;
  background: #ffffff;
  color: #344054;
  border-radius: 999px;
  padding: 4px 8px;
  font-size: 12px;
  cursor: crosshair;
  line-height: 1;
}

.workflow-port.output {
  border-color: #9dbfe2;
  background: #f1f7ff;
  color: #245a9a;
}

.workflow-port.input {
  border-color: #a9c8e8;
  background: #eef5ff;
  color: var(--accent);
}

.workflow-port.connecting {
  outline: 3px solid rgba(47, 109, 183, 0.2);
}

.workflow-empty-state {
  position: absolute;
  left: 50%;
  top: 45%;
  transform: translate(-50%, -50%);
  color: var(--muted);
  border: 1px dashed #b8c2d2;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.9);
  padding: 18px 22px;
}

.workflow-stage-wrap[data-render-state="ready"][data-empty="false"] .workflow-empty-state {
  display: none !important;
}

.workflow-stage-wrap:is([data-render-state="loading"], [data-render-state="rendering"]) .workflow-empty-state {
  color: transparent;
  font-size: 0;
  line-height: 0;
  pointer-events: none;
}

.workflow-stage-wrap:is([data-render-state="loading"], [data-render-state="rendering"]) .workflow-empty-state::before {
  content: "工作流加载中...";
  color: var(--muted);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 800;
}

.workflow-minimap {
  position: absolute;
  right: 14px;
  bottom: 66px;
  width: 184px;
  height: 118px;
  border: 1px solid #c7d3e2;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 12px 28px rgba(20, 31, 48, 0.12);
  overflow: hidden;
  cursor: pointer;
  z-index: 4;
}

.workflow-minimap[hidden] {
  display: none;
}

.workflow-minimap-nodes,
.workflow-minimap-viewport {
  position: absolute;
  inset: 0;
}

/* 点色由 JS 内联给出(hybridNodeAccent，与节点标题栏同源)，不再按 data-category 在 CSS 配色。 */
.workflow-minimap-node {
  position: absolute;
  border-radius: 2px;
}

.workflow-minimap-node.disabled {
  opacity: 0.35;
}

.workflow-minimap-viewport {
  border: 2px solid var(--accent);
  border-radius: 4px;
  background: rgba(47, 109, 183, 0.08);
}

.workflow-status-row {
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  background: #ffffff;
}

.workflow-history-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.workflow-inspector-body {
  display: grid;
  gap: 12px;
  margin-top: 12px;
}

.workflow-inspector-empty,
.workflow-check-list {
  color: var(--muted);
  border: 1px dashed #b8c2d2;
  border-radius: 8px;
  padding: 12px;
  background: #ffffff;
}

.workflow-field {
  display: grid;
  gap: 7px;
}

.workflow-folder-picker {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
}

.workflow-folder-picker input[readonly] {
  cursor: default;
  background: #f8fafc;
}

.workflow-watermark-picker input[readonly] {
  background: #f4fbf7;
  border-color: #a9c8e8;
  color: var(--accent-strong);
}

.workflow-folder-picker button {
  min-height: 38px;
  white-space: nowrap;
}

.workflow-toggle-field {
  grid-template-columns: 1fr auto;
  align-items: center;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #ffffff;
}

.workflow-field textarea {
  min-height: 96px;
}

.workflow-meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  color: var(--muted);
  font-size: 12px;
}

.workflow-task-estimate {
  display: grid;
  gap: 4px;
  border: 1px solid #cfe0f0;
  border-radius: 8px;
  background: #f4fbf7;
  padding: 10px 12px;
}

.workflow-task-estimate strong {
  color: var(--accent-strong);
  font-size: 13px;
}

.workflow-task-estimate span {
  color: #0f172a;
  font-weight: 700;
}

.workflow-task-estimate small {
  color: var(--muted);
}

.workflow-dropped-images {
  display: grid;
  gap: 8px;
  border: 1px solid #cfe0f0;
  border-radius: 8px;
  background: #f4fbf7;
  padding: 10px;
}

.workflow-dropped-images.drag-over {
  border-color: var(--accent);
  background: #eaf2fb;
}

.workflow-dropped-images strong {
  color: var(--accent-strong);
  font-size: 13px;
}

.workflow-dropped-images > div {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(54px, 1fr));
  gap: 8px;
}

.workflow-dropped-images .selected-preview {
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  min-height: 132px;
  max-height: 360px;
  margin: 0;
}

.workflow-dropped-images .selected-thumb {
  background: #ffffff;
}

.workflow-dropped-images .selected-thumb video {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 6px;
  background: #eef2ff;
}

.workflow-dropped-images .workflow-start-media-thumb {
  border-color: rgba(47, 109, 183, 0.25);
  background: linear-gradient(180deg, #ffffff 0%, #f3f8ff 100%);
}

.workflow-start-media-preview {
  display: grid;
  width: 100%;
  aspect-ratio: 1;
  place-items: center;
  gap: 5px;
  border: 1px solid rgba(47, 109, 183, 0.18);
  border-radius: 6px;
  background: #eef6ff;
  color: #215f9d;
}

.workflow-start-media-symbol {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 1px solid rgba(47, 109, 183, 0.22);
  border-radius: 999px;
  background: #ffffff;
  color: #2f6db7;
  font-size: 22px;
  font-weight: 850;
  line-height: 1;
}

.workflow-start-media-preview strong {
  color: #215f9d;
  font-size: 12px;
  font-weight: 850;
}

.workflow-audio-thumb {
  width: 100%;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 6px;
  background: #fff7ed;
  color: #9a3412;
  font-weight: 800;
  font-size: 13px;
}

/* 文本媒体小块：和图片/音频块同尺寸,显示文本片段(像图片一样的一块) */
.workflow-text-thumb {
  background: #eef4ff;
  color: #1f4f7d;
  font-weight: 600;
  font-size: 10.5px;
  line-height: 1.35;
  padding: 6px;
  text-align: left;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  place-items: stretch;
}

.workflow-dropped-images .workflow-dropped-empty {
  display: block; /* 盖过 .workflow-dropped-images > div 的栅格，否则文案被挤进 54px 窄列 */
  border: 1px dashed #c1d4ea;
  border-radius: 8px;
  background: #ffffff;
  color: var(--muted);
  padding: 12px;
  font-size: 13px;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.workflow-dropped-images .workflow-dropped-empty:hover {
  border-color: var(--accent);
  background: #f4f9ff;
  color: var(--accent-strong);
}
.workflow-dropped-images .workflow-dropped-upload {
  justify-self: start;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: #eaf2fb;
  color: var(--accent-strong);
  font-weight: 750;
  font-size: 12.5px;
  padding: 6px 12px;
  cursor: pointer;
}
.workflow-dropped-images .workflow-dropped-upload:hover {
  background: var(--accent);
  color: #fff;
}

.workflow-dropped-images .workflow-media-ingress-thumb {
  cursor: default;
}

.workflow-dropped-images .workflow-media-ingress-actions {
  display: flex;
  gap: 5px;
  padding: 0 5px 5px;
}

.workflow-dropped-images .workflow-media-ingress-actions[hidden] {
  display: none !important;
}

.workflow-dropped-images .workflow-media-ingress-actions button {
  flex: 1 1 0;
  min-width: 0;
  border: 1px solid rgba(180, 35, 24, 0.28);
  border-radius: 6px;
  background: #fff;
  color: #b42318;
  font-size: 11px;
  font-weight: 750;
  padding: 4px 5px;
  cursor: pointer;
}

.workflow-node-help {
  border: 1px solid #d4dce8;
  border-radius: 8px;
  background: #ffffff;
  padding: 10px 12px;
}

.workflow-node-help summary {
  cursor: pointer;
  font-weight: 800;
}

.workflow-node-help p {
  margin: 8px 0;
  color: var(--muted);
  line-height: 1.45;
}

.workflow-help-grid {
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 6px 10px;
  margin: 8px 0;
  font-size: 12px;
}

.workflow-help-grid span,
.workflow-node-help small {
  color: var(--muted);
}

.workflow-help-grid strong {
  color: #344054;
  font-weight: 700;
}

.command-palette-panel {
  width: min(420px, calc(100vw - 24px));
}

.workflow-project-panel {
  display: flex;
  flex-direction: column;
  width: min(920px, calc(100dvw - (var(--modal-edge, 14px) * 2)));
  height: min(720px, calc(100dvh - (var(--modal-edge, 14px) * 2)));
  min-height: 0;
}

.workflow-media-library-panel {
  width: min(1180px, calc(100dvw - (var(--modal-edge, 14px) * 2)));
  height: min(780px, calc(100dvh - (var(--modal-edge, 14px) * 2)));
  min-height: 0;
  --workflow-media-card-min: 176px;
  --workflow-media-card-max: 204px;
  --workflow-media-preview-ratio: 1 / 1;
}

/* 与分享面板头部的副标题同档（见 :root 的 --panel-fs-*）——两个面板的头部现在一眼看上去是一套 */
.workflow-project-status {
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--panel-fs-note);
}

/* 项目库工具栏：搜索独占一行，其余按钮（含社区/分享注入按钮）整齐换行，不再挤压。 */
.workflow-project-tools {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.workflow-project-tools > input[type="search"] {
  flex: 1 1 100%;
  min-width: 0;
}

.workflow-project-tools > button {
  flex: 0 0 auto;
  min-height: var(--panel-h-action);
}

.workflow-media-library-tools {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 140px auto auto;
  gap: 8px;
  margin-bottom: 12px;
  background: #ffffff;
}

.workflow-media-library-panel {
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - (var(--modal-edge, 14px) * 2));
  overflow: hidden;
}

/* 生成库/媒体库切换、拖放提示、关闭按钮同排：填满原本大片留白的头部一行。 */
.workflow-media-library-panel > .modal-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  flex: 0 0 auto;
  gap: 8px 12px;
  margin: 0 0 12px;
  padding: 0;
  border: 0;
  background: transparent;
}

.workflow-media-library-panel > .modal-head > .workflow-media-library-switch {
  align-self: center;
  margin: 0;
}

.workflow-media-library-panel > .modal-head > .workflow-media-library-head-actions {
  margin-left: auto;
  min-width: 0;
}

.workflow-media-library-head-actions > #closeWorkflowMediaLibraryBtn {
  flex: 0 0 auto;
}

.workflow-media-library-hint {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 窄屏：切换 + 关闭同排，提示换到下一整行，避免头部挤成一坨。 */
@media (max-width: 820px) {
  .workflow-media-library-panel > .modal-head > .workflow-media-library-head-actions {
    order: 2;
  }

  .workflow-media-library-hint {
    order: 3;
    flex: 1 1 100%;
    text-align: left;
    font-size: 11.5px;
  }
}

.workflow-media-library-switch {
  position: relative;
  z-index: 4;
  display: inline-grid;
  grid-template-columns: repeat(2, minmax(94px, 1fr));
  align-self: start;
  gap: 4px;
  margin: 0 0 12px;
  padding: 4px;
  border: 1px solid #dce7f3;
  border-radius: 12px;
  background: #f6f9fd;
}

.workflow-media-library-switch button {
  min-height: 34px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: #53657d;
  font-weight: 850;
  cursor: pointer;
}

.workflow-media-library-switch button.active {
  background: #ffffff;
  color: var(--accent-strong);
  box-shadow: 0 8px 18px rgba(47, 109, 183, 0.12), inset 0 0 0 1px rgba(47, 109, 183, 0.16);
}

.workflow-media-library-switch button:disabled {
  cursor: not-allowed;
  opacity: 0.52;
}

.workflow-media-library-view {
  min-height: 0;
}

.workflow-media-library-view.is-active {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.workflow-media-library-view[hidden] {
  display: none !important;
}

.workflow-media-library-list {
  position: relative;
  z-index: 1;
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: repeat(auto-fill, minmax(var(--workflow-media-card-min, 224px), var(--workflow-media-card-max, 1fr)));
  /* 行高必须内容驱动:挑选模式下列表被 flex 定高,auto 行会把可收缩的卡片(overflow:hidden)
     均分压成 ~55px 细条(2026-06-11 实测)。max-content 保证每行=卡片自然高度,容器滚动。 */
  grid-auto-rows: max-content;
  align-content: start;
  gap: 14px;
  width: 100%;
  min-height: 0;
  max-height: none;
  overflow: auto;
  padding: 4px 6px 24px 2px;
  box-sizing: border-box;
}

.workflow-media-library-list > .workflow-project-empty {
  grid-column: 1 / -1;
  align-self: stretch;
  display: grid;
  place-items: center;
  width: 100%;
  min-height: min(320px, 100%);
  box-sizing: border-box;
}

.workflow-media-upload-view {
  gap: 10px;
}

.workflow-media-upload-drop {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 12px;
  min-height: 58px;
  padding: 10px 12px;
  border: 1.5px dashed #b9cce3;
  border-radius: 14px;
  background: linear-gradient(180deg, #f8fbff, #f2f7fd);
  color: #58708c;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, box-shadow 160ms ease, background 160ms ease;
}

.workflow-media-upload-drop strong {
  color: #172033;
  font-size: 14px;
  font-weight: 900;
  white-space: nowrap;
}

.workflow-media-upload-drop span {
  min-width: 0;
  font-size: 12px;
  line-height: 1.35;
}

.workflow-media-upload-drop button {
  justify-self: end;
}

.workflow-media-upload-drop.is-dragging,
.workflow-media-upload-drop:focus-visible {
  border-color: var(--accent);
  background: #eef6ff;
  box-shadow: 0 0 0 4px rgba(47, 109, 183, 0.12);
  outline: none;
}

.workflow-media-upload-list {
  flex: 1 1 360px;
  min-height: 0;
}

.workflow-media-upload-pending-card {
  border-style: dashed;
  border-color: rgba(47, 109, 183, 0.42);
  background: linear-gradient(180deg, #ffffff, #f7fbff);
}

.workflow-media-upload-pending-card.is-uploading {
  opacity: 0.72;
  cursor: wait;
}

.workflow-media-upload-pending-card .workflow-media-library-select {
  display: none;
}

.workflow-media-upload-pending-badge {
  position: absolute;
  z-index: 2;
  right: 10px;
  top: 10px;
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 9px;
  border-radius: 999px;
  background: rgba(47, 109, 183, 0.92);
  color: #ffffff;
  font-size: 12px;
  font-weight: 850;
  box-shadow: 0 8px 18px rgba(47, 109, 183, 0.18);
}

body.theme-dark .workflow-media-library-switch {
  border-color: rgba(141, 149, 165, 0.26);
  background: rgba(13, 21, 34, 0.68);
}

body.theme-dark .workflow-media-library-switch button {
  color: #a9bace;
}

body.theme-dark .workflow-media-library-switch button.active,
body.theme-dark .workflow-media-upload-pending-card {
  background: rgba(18, 21, 29, 0.82);
  color: #dce8f6;
  border-color: rgba(141, 149, 165, 0.24);
}

body.theme-dark .workflow-media-upload-drop {
  border-color: rgba(141, 149, 165, 0.26);
  background: rgba(13, 21, 34, 0.7);
  color: #a9bace;
}

body.theme-dark .workflow-media-upload-drop strong,
body.theme-dark .workflow-media-upload-pending-card .workflow-media-library-title strong {
  color: #edf5ff;
}

.workflow-media-library-card {
  position: relative;
  z-index: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 0;
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  background: #ffffff;
  padding: 0;
  cursor: grab;
  overflow: hidden;
  /* 选中闪烁根治(手机真机+高DPR):基态预留和 .is-selected 完全相同几何的透明 box-shadow 槽(环+柔影),
     选中只把透明染成颜色。GPU 上 box-shadow 外扩几何一变会作废/重栅格圆角卡的合成 surface=闪一帧;
     几何恒定就不重分配。transition 从 none 改成过渡颜色(不硬跳);z-index 不再随选中切换(避免合成层重排)。 */
  box-shadow: 0 0 0 3px transparent, 0 18px 42px transparent;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

.workflow-media-library-card.is-selected {
  border-color: rgba(47, 109, 183, 0.72);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.12), 0 18px 42px rgba(15, 23, 42, 0.08);
}

.workflow-media-library-card:hover {
  border-color: rgba(47, 109, 183, 0.28);
  box-shadow: 0 0 0 3px transparent, 0 18px 42px rgba(15, 23, 42, 0.08);
}

.workflow-media-library-card.is-selected:hover {
  border-color: rgba(47, 109, 183, 0.78);
  box-shadow: 0 0 0 3px rgba(47, 109, 183, 0.14), 0 18px 42px rgba(15, 23, 42, 0.1);
}

.workflow-media-library-select {
  position: absolute;
  z-index: 3;
  top: 10px;
  left: 10px;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 26px;
  min-width: 26px;
  max-width: 26px;
  height: 26px;
  min-height: 26px;
  max-height: 26px;
  padding: 0;
  border: 1px solid rgba(47, 109, 183, 0.36);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.88);
  color: #ffffff;
  font-size: 15px;
  font-weight: 900;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(8px);
}

.infinite-card textarea::placeholder,
.infinite-card-inline-panel textarea::placeholder {
  color: rgba(83, 90, 104, 0.62);
}

.workflow-media-library-select[aria-pressed="true"] {
  border-color: #2f6db7;
  background: #2f6db7;
}

.workflow-media-library-card:active {
  cursor: grabbing;
}

.workflow-media-library-card.dragging {
  cursor: grabbing;
}

.workflow-media-library-preview {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: auto;
  min-height: 0;
  aspect-ratio: var(--workflow-media-preview-ratio, 1 / 1);
  border: 0;
  border-bottom: 1px solid #e4ecf5;
  border-radius: 0;
  /* 棋盘格底：透明 PNG / 浅色全景图也能被清晰框住，不再糊成空白（与水印预览统一风格） */
  background:
    linear-gradient(45deg, rgba(148, 163, 184, 0.12) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(148, 163, 184, 0.12) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(148, 163, 184, 0.12) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(148, 163, 184, 0.12) 75%),
    #f4f7fb;
  background-position: 0 0, 0 9px, 9px -9px, -9px 0;
  background-size: 18px 18px;
  overflow: hidden;
  padding: 0;
  cursor: zoom-in;
}
/* 视频居中播放按钮 */
.workflow-media-library-preview .media-play-badge {
  position: absolute;
  inset: auto;
  width: 34px;
  height: 34px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(4px);
  pointer-events: none;
}
.workflow-media-library-preview .media-play-badge::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 53%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 7px 0 7px 11px;
  border-color: transparent transparent transparent #ffffff;
}

.workflow-media-library-preview img,
.workflow-media-library-preview video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 缩略图加载失败（媒体已删/失效）时的占位，避免出现纯空白卡 */
.workflow-media-library-preview.preview-broken img,
.workflow-media-library-preview.preview-broken video {
  display: none;
}
.workflow-media-library-preview.preview-broken::after {
  content: "缩略图暂不可用";
  color: #94a4b8;
  font-size: 11.5px;
  padding: 0 10px;
  text-align: center;
}

.workflow-media-library-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: #eaf2fb;
  color: var(--accent-strong);
  font-weight: 850;
}
.workflow-media-library-icon svg {
  width: 24px;
  height: 24px;
}
.workflow-media-library-icon.kind-audio {
  background: #eaf0ff;
  color: #3a64c8;
}
.workflow-media-library-icon.kind-text {
  background: #eef2f6;
  color: #5a6b82;
}

.workflow-media-library-meta {
  min-width: 0;
  padding: 10px 12px 12px;
}

.workflow-media-library-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.workflow-media-library-title strong {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #111827;
  font-size: 13px;
  font-weight: 850;
}

.workflow-media-library-title span {
  flex: 0 0 auto;
  border-radius: 999px;
  background: #eef5ff;
  color: #245a9a;
  padding: 2px 7px;
  font-size: 11px;
  font-weight: 780;
}

.workflow-media-library-meta p {
  margin: 6px 0 5px;
  min-height: 18px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.42;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.workflow-media-library-meta small {
  display: block;
  color: #667085;
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.workflow-media-library-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 5px;
  margin-top: 7px;
}

.workflow-media-library-actions button {
  min-height: 24px;
  border: 1px solid #cfe0f1;
  border-radius: 8px;
  background: #f7fbff;
  color: #235a96;
  font-size: 10.5px;
  font-weight: 850;
  cursor: pointer;
}

.workflow-media-library-actions button:hover {
  border-color: rgba(47, 109, 183, 0.32);
  background: #eaf2fb;
  color: #2f6db7;
}

/* 卡片图片底部悬浮操作条：下载 / 删除，复用任务卡片 .gen-tools/.gen-icon-btn 磨砂方块视觉。
   默认隐藏，悬停/聚焦/选中时淡入；触摸端(无 hover)常显，保证仍可点。 */
.workflow-media-library-actbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  padding: 8px;
  background: linear-gradient(to top, rgba(15, 23, 42, 0.6), rgba(15, 23, 42, 0));
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 3;
}

.workflow-media-library-preview:hover .workflow-media-library-actbar,
.workflow-media-library-card:focus-within .workflow-media-library-actbar,
.workflow-media-library-card.is-selected .workflow-media-library-actbar {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

@media (hover: none) {
  .workflow-media-library-actbar {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
}

/* 媒体库详情：复用结果详情 feed-detail 的大预览与侧栏，只补媒体类型差异。 */
.media-detail-mask {
  z-index: var(--z-modal-priority);
}

.media-detail-zoom-target {
  transform-origin: center center;
  will-change: transform;
}

/* 媒体库音频详情:卡片放大占满预览区(与图片/视频撑满统一),不再是小块居中大片留白。 */
.media-detail-audio {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  width: min(680px, 94%);
  height: min(560px, 100%);
  min-height: 320px;
  padding: 32px;
  border-radius: 18px;
  background: linear-gradient(135deg, #eef5ff, #f7fbff);
}

.media-detail-audio svg {
  width: 64px;
  height: 64px;
  color: #3a64c8;
}

.media-detail-audio audio {
  width: min(560px, 100%);
}

.media-detail-fileicon {
  display: grid;
  place-items: center;
  min-height: 320px;
}

.media-detail-fileicon svg {
  width: 58px;
  height: 58px;
  color: #5a6b82;
}

.media-detail-kind-audio .media-detail-preview,
.media-detail-kind-file .media-detail-preview {
  cursor: default;
}

.media-detail-actions .ui-icon {
  width: 16px;
  height: 16px;
}

body.theme-dark:not(.auth-required) .media-detail-audio {
  background: rgba(13, 21, 34, 0.86);
}

@media (max-width: 760px) {
  .media-detail-audio,
  .media-detail-fileicon {
    min-height: 260px;
  }
}

@media (max-width: 1120px) {
  .workflow-media-library-list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 860px) {
  .workflow-media-library-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* 通用框选矩形(installBoxSelectGesture 引擎):媒体库/生成库/上传队列/任务结果区共用同一视觉 */
.workflow-media-library-selection-box,
.app-box-select-rect {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  border: 1px solid rgba(47, 109, 183, 0.72);
  border-radius: 12px;
  background: rgba(47, 109, 183, 0.1);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.45);
}

.workflow-media-library-drag-badge {
  position: fixed;
  z-index: var(--z-drag-ghost);
  top: -1000px;
  left: -1000px;
  border-radius: 999px;
  background: #2f6db7;
  color: #ffffff;
  padding: 8px 13px;
  font-size: 13px;
  font-weight: 850;
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.18);
}

.workflow-media-library-card-ghost {
  position: fixed;
  z-index: var(--z-drag-ghost);
  width: 92px;
  height: 92px;
  margin: 0;
  /* 以定位点为中心（left/top 直接给手指坐标即可居中，与幽灵尺寸无关 → 改大小也始终跟手）。 */
  transform: translate(-50%, -50%);
  pointer-events: none;
  border: 2px solid #2f6db7;
  border-radius: 12px;
  overflow: hidden;
  background-color: #0d1320;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.4);
  opacity: 0.97;
}

.workflow-media-library-card-ghost.is-text {
  display: grid;
  place-items: center;
  padding: 8px;
  background-color: #ffffff;
  color: #2f6db7;
  font-size: 12px;
  font-weight: 800;
  text-align: center;
  word-break: break-all;
}

.workflow-media-library-card.is-drag-source {
  opacity: 0.3;
}

.workflow-media-library-ghost-count {
  position: absolute;
  top: 6px;
  right: 6px;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  background: #2f6db7;
  color: #ffffff;
  font-size: 12px;
  font-weight: 800;
  z-index: 3;
}

.workflow-media-library-drag-ghost {
  position: fixed;
  z-index: var(--z-drag-ghost);
  top: 0;
  left: 0;
  max-width: 220px;
  pointer-events: none;
  border: 1px solid rgba(47, 109, 183, 0.3);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.94);
  color: #2f6db7;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 850;
  box-shadow: 0 16px 34px rgba(15, 23, 42, 0.16);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 980px), (max-height: 760px) {
  body:not(.auth-required) :is(.workflow-project-panel, .workflow-media-library-panel) {
    height: calc(100dvh - (var(--modal-edge, 12px) * 2));
    border-radius: 14px;
    padding: 14px;
  }

  body:not(.auth-required) .workflow-media-library-panel {
    --workflow-media-card-min: 158px;
    --workflow-media-card-max: 1fr;
  }

  body:not(.auth-required) .workflow-media-library-tools {
    grid-template-columns: minmax(0, 1fr) minmax(120px, 0.35fr) auto auto;
    gap: 7px;
  }

  body:not(.auth-required) .workflow-media-upload-drop {
    min-height: 54px;
  }

  body:not(.auth-required) .workflow-project-list {
    grid-template-columns: repeat(auto-fill, minmax(204px, 1fr));
  }

  body:not(.auth-required) .canvas-project-list {
    grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
  }
}

@media (max-width: 760px) {
  body:not(.auth-required) .workflow-media-library-tools {
    grid-template-columns: minmax(0, 1fr) minmax(106px, 0.4fr);
  }

  body:not(.auth-required) .workflow-media-library-tools > input[type="search"] {
    grid-column: 1 / -1;
  }

  body:not(.auth-required) .workflow-media-library-tools > button {
    min-width: 0;
  }
}

/* 项目库（工作流 + 无限画布）统一卡片：封面横幅 → 标题/信息 → 等宽操作行，纵向堆叠。 */
.workflow-project-list {
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
  align-content: start;
  gap: 14px;
  min-height: 0;
  max-height: none;
  overflow: auto;
  padding: 2px 4px 4px 2px;
}

.workflow-project-card {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: #ffffff;
  padding: 10px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.workflow-project-card:hover {
  border-color: rgba(47, 109, 183, 0.45);
  box-shadow: 0 10px 26px rgba(16, 24, 40, 0.1);
  transform: translateY(-2px);
}

.canvas-project-panel {
  width: min(1040px, calc(100dvw - (var(--modal-edge, 14px) * 2)));
}

.canvas-project-list {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.canvas-project-card {
  border-radius: 14px;
  padding: 10px;
  overflow: hidden;
}

/* 统一封面：满宽横幅，点阵画布底（呼应真实画布观感），布局缩略块浮在其上 */
.canvas-project-preview {
  position: relative;
  width: 100%;
  height: 106px;
  min-height: 106px;
  border: 1px solid rgba(31, 45, 65, 0.08);
  border-radius: 11px;
  background:
    radial-gradient(rgba(47, 109, 183, 0.18) 1px, transparent 1.6px),
    linear-gradient(160deg, #f7fafd 0%, #edf3fa 100%);
  background-size: 14px 14px, 100% 100%;
  overflow: hidden;
  cursor: pointer;
  padding: 0;
  transition: border-color 0.16s ease;
}

.project-card:hover .canvas-project-preview {
  border-color: rgba(47, 109, 183, 0.32);
}

.project-card-cover-workflow {
  display: grid;
  place-items: center;
  color: #7d95b4;
}

.project-card-cover-glyph svg { width: 58px; height: 38px; opacity: 0.75; }

/* 「当前」徽章挂封面左上角(替代原标题旁的文字徽章) */
.project-card-flag {
  position: absolute;
  left: 8px;
  top: 8px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #ffffff;
  background: linear-gradient(135deg, #4585d4, #2f6db7);
  border-radius: 999px;
  padding: 2px 9px;
  box-shadow: 0 2px 8px rgba(47, 109, 183, 0.38);
  pointer-events: none;
}

.project-card-cover-run {
  position: absolute;
  right: 7px;
  top: 7px;
}

/* 卡片信息区：统计行 + 底部「时间 | 图标动作」 */
.project-card-meta {
  font-size: var(--panel-fs-note);
  line-height: 1.4;
  color: var(--muted);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.project-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  border-top: 1px solid rgba(31, 45, 65, 0.07);
  padding-top: 7px;
  margin-top: auto;
}

.project-card-time {
  font-size: var(--panel-fs-note);
  color: #74839a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.project-card-foot .workflow-project-actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: none;
}

.project-icon-btn {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #5d6b81;
  cursor: pointer;
  transition: background 0.13s ease, color 0.13s ease;
}

.project-icon-btn:hover { background: rgba(47, 109, 183, 0.1); color: #2f6db7; }
.project-icon-btn.project-icon-danger:hover { background: rgba(217, 60, 74, 0.1); color: #d93c4a; }
.project-icon-btn[disabled] { opacity: 0.35; cursor: not-allowed; }
.project-icon-btn[disabled]:hover { background: transparent; color: #5d6b81; }

.project-icon-btn svg {
  width: 15px;
  height: 15px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 项目库空态：居中图标 + 主副文案 */
.workflow-project-empty.project-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  text-align: center;
  padding: 46px 18px;
  color: var(--muted);
}

.project-empty-icon {
  display: grid;
  place-items: center;
  width: 74px;
  height: 56px;
  border-radius: 14px;
  color: #8ba3c0;
  background: linear-gradient(160deg, #f2f7fc, #e9f1fa);
  margin-bottom: 4px;
}

.project-empty-icon svg { width: 44px; height: 32px; }

.workflow-project-empty.project-empty strong {
  font-size: 14px;
  color: var(--text);
}

.workflow-project-empty.project-empty > span:not(.project-empty-icon) {
  font-size: 12.5px;
}

/* ── 音乐工具 · Suno 参数区（顶部模式切换 + 平铺表单 + 同款参考音频） ── */
.music-mode-block{display:flex;flex-direction:column;gap:7px}
/* 顶部位置(替换原「音乐/语音」大 tabs):对齐图片模块顶部 tabs 的体量与留白 */
.music-mode-block-top{margin:0 0 var(--panel-padding)}
/* 音乐模式 tabs 已改用全站 .tabs/.tab(与图片模块生图/改图同款,2026-07-05),旧样式删除 */
.music-mode-hint{margin:0;font-size:12px;line-height:1.5;color:#7c90a5;padding:0 4px}
.music-required{color:#d8413a;font-weight:800}
body.theme-dark:not(.auth-required) .music-mode-hint{color:#8aa0bb}
.music-label-line{display:inline-flex;align-items:center;gap:4px}
