.generate-node.compact-node,
.video-node.compact-node,
.image-node.compact-node {
  width: 240px;
  padding: 10px;
  border-radius: var(--ai2-r-node);
  background: #fff;
  border: 1px solid #e3e7ea;
  box-shadow: 0 18px 50px rgba(24,32,38, .08);
}

.generate-node.compact-node .node-header,
.image-node.compact-node .node-header,
.video-node.compact-node .node-header {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 28px;
  margin: 0 2px 8px;
  padding: 0;
  color: #667078;
}

.compact-node .node-title {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  color: #667078;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.compact-node .node-title span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 双击标题就地改名：图片节点的标题带原本是 pointer-events: none（整条标题只是浮层），
   只把标题本身放出来接事件，别的一律照旧穿透。 */
.bare-image-node > .node-header .node-title {
  pointer-events: auto;
  cursor: text;
}

/* 重命名输入框：比标题大一号，浮在标题带上，改的时候看得清。
   用 #root 前缀 + !important 是因为统一表单样式会把 input 钉成 13px。 */
#root .ai2-rename-input {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 320;
  min-width: 220px;
  max-width: 68vw;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--ai2-accent, #526df5) !important;
  border-radius: var(--ai2-r-field, 14px) !important;
  background: var(--ai2-surface, #fff) !important;
  color: var(--ai2-text, #171a1d) !important;
  font-size: 18px !important;
  font-weight: 700;
  line-height: 1;
  outline: none;
  box-shadow: 0 12px 30px rgba(24, 32, 38, .18);
}

.compact-node .node-header-right {
  flex: 0 0 auto;
  color: #9aa2a9;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.compact-node .node-status {
  display: none;
}

.compact-stage {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  border: 0;
  padding: 0;
  border-radius: var(--ai2-r-field);
  background: #f1f3f5;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}

.compact-stage:active {
  transform: translateY(0) scale(0.99);
}

.video-node.compact-node,
.video-node.compact-node .compact-stage {
  width: 320px !important;
}

.video-node.compact-node .compact-stage {
  aspect-ratio: 4 / 3;
}

.compact-stage img,
.compact-stage video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.compact-placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 7px;
  color: #9aa2a9;
  background: linear-gradient(180deg, #f7f8fa 0%, #f1f3f5 100%);
}

.compact-placeholder small {
  font-size: 11px;
}

.compact-upload-overlay {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: #667078;
  box-shadow: 0 8px 22px rgba(24,32,38, .16);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, transform 0.12s ease;
}

/* hover 只给尺寸反馈：底色和图标色钉在静止值，压掉后面那条全局暖桃 hover。
   带 .node-shell 前缀是为了比它高一级特异性（两边都是 !important）。 */
.node-shell .compact-upload-overlay:hover {
  background: rgba(255, 255, 255, .9) !important;
  color: #667078 !important;
  transform: scale(1.08);
}

/* 运行态不再显示右下角的转圈角标。元素必须留在 DOM 里：
   ai2-node-run-anim.js 靠 :scope > .compact-running 判定运行状态。 */
.compact-running {
  display: none !important;
}

.compact-top {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: visible !important;
  padding: 7px;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  border: 1px solid #e3e7ea;
  box-shadow: 0 16px 38px rgba(24,32,38, .14);
  z-index: 80;
}

.compact-icon-btn {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: #f1f3f5;
  color: #667078;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, transform 0.12s ease;
}

.compact-icon-btn:hover:not(:disabled) {
  background: #eef1ff;
  color: #3f55c4;
  transform: translateY(-1px);
}

.compact-icon-btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

/* ==========================================================================
   图片节点二级菜单：参考图那种「图标 + 文字」排法。
   配色沿用现有中性色（白底 / 灰字 / 蓝选中），只改结构与层级：
   整条是胶囊，项与项之间一条细分隔线，普通项透明，悬停或选中才是浅色胶囊。
   裁剪、画笔两个按钮由裁剪/画笔补丁插进来，它们本来就带 .compact-icon-btn，
   这里用 ::after 把标签补上，不用改那两个脚本。
   ========================================================================== */
#root .image-node.compact-node > .compact-top {
  gap: 2px;
  padding: 6px 8px;
  box-shadow: var(--ai2-shadow-float, 0 16px 38px rgba(24, 32, 38, .14)) !important;
}

#root .image-node.compact-node > .compact-top > .compact-icon-btn,
#root .image-node.compact-node > .compact-top > .compact-multi-toggle {
  position: relative;
  width: auto !important;
  min-width: 0;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 0 !important;
  border-radius: 999px !important;
  background: transparent !important;
  color: var(--ai2-text-2, #667078) !important;
  box-shadow: none !important;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
}

#root .image-node.compact-node > .compact-top > .compact-icon-btn svg,
#root .image-node.compact-node > .compact-top > .compact-multi-toggle svg {
  flex: 0 0 auto;
}

/* 项之间的细分隔线（第一项不画）。 */
#root .image-node.compact-node > .compact-top > * + *::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 50%;
  height: 16px;
  transform: translateY(-50%);
  border-left: 1px solid var(--ai2-line, #edeff2);
  pointer-events: none;
}

/* 悬停：浅色胶囊；多图入口展开时用浅蓝底 + 蓝字，沿用既有强调色。 */
#root .image-node.compact-node > .compact-top > .compact-icon-btn:hover:not(:disabled),
#root .image-node.compact-node > .compact-top > .compact-multi-toggle:hover {
  background: var(--ai2-hover, #f1f3f5) !important;
  color: var(--ai2-text, #171a1d) !important;
}

#root .image-node.compact-node > .compact-top > .compact-multi-toggle.active {
  background: var(--ai2-accent-soft, #eef1ff) !important;
  color: var(--ai2-accent-text, #3f55c4) !important;
}

#root .image-node.compact-node > .compact-top > .compact-icon-btn:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}

/* 图标旁边的文字标签。 */
#root .image-node.compact-node > .compact-top > .compact-zoom-btn::after { content: "放大"; }
#root .image-node.compact-node > .compact-top > .compact-download-btn::after { content: "下载"; }
#root .image-node.compact-node > .compact-top > .compact-threeview-btn::after { content: "角色三视"; }
#root .image-node.compact-node > .compact-top > .compact-multi-toggle::after { content: "多图"; }
#root .image-node.compact-node > .compact-top > .ai2-crop-trigger::after { content: "裁剪"; }
#root .image-node.compact-node > .compact-top > .ai2-paint-trigger::after { content: "画笔"; }

/* 「角色三视」开着时用浅蓝强调态，和多图入口保持一致。 */
#root .image-node.compact-node > .compact-top > .compact-threeview-btn.active {
  background: var(--ai2-accent-soft, #eef1ff) !important;
  color: var(--ai2-accent-text, #3f55c4) !important;
}

/* 其它节点类型（视频 / 文本 / RunningHub）的工具条沿用旧样式。 */
.compact-top .compact-multi-toggle {
  position: static;
  top: auto;
  right: auto;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #f1f3f5;
  color: #667078;
  box-shadow: none;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.compact-top .compact-multi-toggle:hover,
.compact-top .compact-multi-toggle:focus-visible,
.compact-top .compact-multi-toggle.active {
  background: #eef1ff;
  border-color: transparent;
  color: #3f55c4;
  outline: none;
}

.compact-panel {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  width: min(920px, 94vw);
  padding: 28px;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  border: 1px solid #e3e7ea;
  box-shadow: 0 26px 80px rgba(24,32,38, .16);
  z-index: 90;
}

.compact-textarea {
  width: 100%;
  min-height: 163px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  padding: 22px 26px;
  background: #fff;
  color: #171a1d;
  font-size: 13px;
  line-height: 1.6;
  resize: vertical;
  outline: none;
  font-family: inherit;
}

.compact-textarea:focus {
  border-color: #8e9bf9;
  box-shadow: 0 0 0 3px rgba(82, 109, 245, .22);
}

/* 内置提示词标签：摆在输入框上方（输入框最前面），显示成「图标 + 文字」的 chip。
   提示词正文本身不显示；鼠标移到 chip 上右侧才出现 ×，点它或按退格都能移除。 */
.compact-prompt-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 10px;
}

.compact-prompt-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--ai2-border, #e3e7ea);
  border-radius: 999px !important;
  background: var(--ai2-surface-2, #f7f8fa);
  color: var(--ai2-text-2, #667078);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.compact-prompt-tag-icon { flex: 0 0 auto; }

.compact-prompt-tag-remove {
  width: 16px;
  height: 16px;
  margin-left: 2px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50% !important;
  background: transparent;
  color: var(--ai2-text-3, #9aa2a9);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
}

.compact-prompt-tag:hover .compact-prompt-tag-remove,
.compact-prompt-tag:focus-within .compact-prompt-tag-remove {
  opacity: 1;
}

.compact-prompt-tag-remove:hover,
.compact-prompt-tag-remove:focus-visible {
  background: var(--ai2-hover, #f1f3f5);
  color: var(--ai2-text, #171a1d);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  .compact-prompt-tag-remove { transition: none; }
}

.compact-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 24px;
  flex-wrap: nowrap;
  justify-content: flex-start;
}

.compact-toolbar .node-api-select-row {
  flex: 0 1 auto;
  width: auto;
  min-width: 116px;
  margin: 0;
  height: 46px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--ai2-r-field);
  background: #f1f3f5;
  gap: 6px;
}

.compact-toolbar .node-api-select-row span {
  font-size: 11px;
  font-weight: 700;
  color: #667078;
  flex: none;
}

.compact-toolbar .node-api-select-row select {
  height: 28px;
  min-height: 28px;
  border: 0;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #171a1d;
  font-size: 12px;
  font-weight: 600;
  padding: 0 4px;
  outline: none;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 76px;
  text-overflow: ellipsis;
}

.compact-pill {
  height: 46px;
  border: 0;
  border-radius: var(--ai2-r-field);
  background: #f1f3f5;
  color: #667078;
  padding: 0 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}

.compact-pill span {
  max-width: 132px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.compact-pill:hover,
.compact-pill.active {
  background: #eef1ff;
  color: #3f55c4;
}

.compact-pill.static {
  cursor: default;
}

.platform-list button[draggable="true"] {
  cursor: grab;
}

.platform-list button[draggable="true"]:active {
  cursor: grabbing;
}

.platform-list button.dragging {
  opacity: 0.55;
  outline: 2px dashed #8e9bf9;
  outline-offset: 2px;
}

.platform-list button.drag-over {
  outline: 2px solid #8e9bf9;
  outline-offset: -2px;
  background: rgba(142, 155, 249, .22);
}

/* 上游缩略图：悬停不再原地放大（改由 ai2-thumb-preview.js 弹三级浮层，样式在 ai2-restyle.css）。
   overflow 保持 visible，浮层要能探出面板。 */
.compact-panel .preview-row {
  overflow: visible;
}

.preview-row .preview-thumb img {
  animation-fill-mode: backwards;
}

.preview-row .preview-thumb {
  cursor: grab;
}

/* RunningHub 工作流节点 */
.rh-node-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  color: #9aa2a9;
  margin: 8px 0 4px;
}

.rh-node-label:first-child {
  margin-top: 0;
}

.rh-node-input {
  min-width: 0;
  border: 1px solid #ccd3d9;
  border-radius: var(--ai2-r-field);
  background: #fff;
  padding: 6px 9px;
  font-size: 12px;
  color: #171a1d;
  font-family: inherit;
  outline: none;
}

.rh-node-input:focus {
  border-color: #526df5;
}

.rh-param-head {
  margin-top: 10px;
}

.rh-add-param {
  border: 1px solid #ccd3d9;
  border-radius: var(--ai2-r-field);
  background: #fff;
  color: #3f55c4;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  cursor: pointer;
}

.rh-add-param:hover {
  background: #f7f8fa;
}

.rh-field-row {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 6px;
}

.rh-field-type {
  flex: 0 0 58px;
  cursor: pointer;
}

.rh-field-nodeid {
  flex: 0 0 58px;
}

.rh-field-row > .rh-node-input:not(.rh-field-type):not(.rh-field-nodeid) {
  flex: 1 1 auto;
}

.rh-field-idx {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  color: #3f55c4;
  white-space: nowrap;
}

.rh-field-del {
  flex: 0 0 22px;
  height: 22px;
  border-radius: var(--ai2-r-field);
  border: 1px solid #edeff2;
  background: #fff;
  color: #3f55c4;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.rh-field-del:hover {
  background: #f7f8fa;
}

.rh-settings-box {
  margin-top: 14px;
  border: 1px dashed #ccd3d9;
  border-radius: var(--ai2-r-panel);
  padding: 12px 14px;
  background: #f7f8fa;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.rh-settings-head {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #3f55c4;
  font-size: 13px;
}

.rh-settings-box label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  font-weight: 700;
  color: #667078;
}

.rh-settings-box input {
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  padding: 8px 10px;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  color: #171a1d;
  outline: none;
}

.rh-settings-box input:focus {
  border-color: #526df5;
}

/* 多选虚拟框 + 右侧加号连接把手 */
.multi-sel-box {
  position: fixed;
  border: 1.5px dashed #9aa2a9;
  border-radius: var(--ai2-r-panel);
  pointer-events: none;
  z-index: 40;
}

.multi-sel-plus {
  position: absolute;
  right: -17px;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: #fff;
  color: #3f55c4;
  box-shadow: 0 4px 14px rgba(24,32,38, .16);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  pointer-events: auto;
  padding: 0;
}

.multi-sel-plus:active {
  cursor: grabbing;
}

.multi-sel-line {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 39;
}

.multi-sel-line line {
  stroke: #9aa2a9;
  stroke-width: 2;
  stroke-dasharray: 6 5;
}

/* 缩放控件：横排放到画布历史按钮右侧，同款深色圆底等高 */
.react-flow__controls {
  left: 110px !important;
  right: auto !important;
  bottom: 16px !important;
  top: auto !important;
  margin: 0 !important;
  flex-direction: row !important;
  align-items: center;
  gap: 2px;
  height: 39px;
  padding: 0 6px !important;
  background: rgba(23, 26, 29, .92) !important;
  border-radius: var(--ai2-r-field) !important;
  box-shadow: 0 12px 34px rgba(82, 109, 245, .22) !important;
}

.react-flow__controls-button {
  border: none !important;
  background: transparent !important;
  width: 28px !important;
  height: 31px !important;
  border-radius: var(--ai2-r-field) !important;
  color: #fff !important;
}

.react-flow__controls-button:hover {
  background: rgba(255, 255, 255, .16) !important;
}

.react-flow__controls-button svg {
  fill: #fff !important;
}

/* 画布历史按钮：移到左下角，与缩放控件水平排列 */
#ai2-canvas-history-root {
  left: 18px !important;
  right: auto !important;
  bottom: 16px !important;
  top: auto !important;
}

/* 面板展开时按钮不跟着跳到右侧，始终贴在左下角 */
#ai2-canvas-history-root .ai2-fab-wrap {
  justify-content: flex-start !important;
}

/* 画布缩略图：固定右下角 */
.react-flow__minimap.react-flow__panel {
  right: 14px !important;
  bottom: 14px !important;
  left: auto !important;
  top: auto !important;
}

/* 连线中点：小圆点击放大成剪刀，点击剪刀断开 */
.edge-middle {
  pointer-events: all;
  cursor: pointer;
  transition: opacity 0.12s ease;
  opacity: 0.55;
}

.edge-middle:hover {
  opacity: 1;
}

.edge-cut {
  pointer-events: all;
  cursor: pointer;
}

.edge-cut-circle {
  fill: #fff;
  stroke: #526df5;
  stroke-width: 2;
  pointer-events: all;
  cursor: pointer;
  filter: drop-shadow(0 2px 8px rgba(24,32,38, .16));
}

.edge-cut-icon {
  font-size: 14px;
  fill: #3f55c4;
  pointer-events: none;
  user-select: none;
}

/* 二级菜单（参考稿）：白面板、浅描边输入框、浅色胶囊（选中浅棕描边不高黑） */
.compact-panel {
  padding: 10px 10px 8px !important;
}

.compact-panel .compact-textarea {
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-field) !important;
  background: #fff !important;
}

.compact-pill {
  background: #fff !important;
  border: 1px solid #f1f3f5 !important;
  color: #667078 !important;
  border-radius: var(--ai2-r-field) !important;
  height: 30px !important;
  padding: 0 10px !important;
  box-shadow: none !important;
}

.compact-pill:hover {
  background: #f7f8fa !important;
}

.compact-pill.active {
  background: #f7f8fa !important;
  border-color: #526df5 !important;
}

.compact-pill span {
  color: #667078 !important;
}

.compact-pill .select-label {
  color: #9aa2a9 !important;
  font-weight: 700;
}

.compact-pill .select-val {
  color: #171a1d !important;
  font-weight: 700;
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.compact-pill .select-arrow {
  color: #9aa2a9 !important;
  font-size: 10px !important;
  margin-left: 2px !important;
}

.compact-toolbar { position: relative; }
.compact-pill { position: relative; }
.compact-pill.relative { position: relative; }

.compact-toolbar .compact-pill > .option-popover,
.compact-toolbar .compact-pill > .option-popover,
.compact-node .compact-pill > .option-popover,
.compact-node .compact-pill > .compact-size-popover,
.compact-toolbar .compact-pill > .compact-size-popover,
.compact-toolbar .compact-pill.active ~ .option-popover,
.compact-toolbar .compact-size-popover .option-popover,
.wf-pop .option-popover {
  position: absolute !important;
  left: 0 !important;
  right: auto !important;
  bottom: calc(100% + 8px) !important;
  top: auto !important;
  transform: none !important;
  width: max-content !important;
  min-width: 180px !important;
  max-width: 260px !important;
  max-height: 240px !important;
  overflow-y: auto !important;
  margin: 0 !important;
  z-index: 40;
  background: #fff !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-field) !important;
  box-shadow: 0 14px 40px rgba(24,32,38, .16) !important;
  padding: 6px !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 4px !important;
  align-items: stretch !important;
}

.compact-toolbar .option-popover button,
.wf-pop .option-popover button {
  width: 100% !important;
  min-height: 34px !important;
  height: 34px !important;
  border-radius: var(--ai2-r-field) !important;
  background: transparent !important;
  color: #667078 !important;
  justify-content: flex-start !important;
  text-align: left !important;
  padding: 0 10px !important;
  font-size: 12px !important;
  border: none !important;
}

.compact-toolbar .option-popover button:hover,
.wf-pop .option-popover button:hover {
  background: #f7f8fa !important;
  color: #171a1d !important;
}

.compact-toolbar .option-popover button.active,
.wf-pop .option-popover button.active {
  background: #e3e7ea !important;
  color: #171a1d !important;
  font-weight: 700;
}

/* 清晰度+比例弹层（含两组选项）：同样贴工具条上方 */
.compact-toolbar .compact-pill.active ~ .compact-size-popover {
  position: absolute !important;
  left: 0 !important;
  right: auto !important;
  bottom: calc(100% + 8px) !important;
  top: auto !important;
  transform: none !important;
  width: 240px !important;
  max-width: none !important;
  margin: 0 !important;
  z-index: 40;
  background: #fff !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-panel) !important;
  box-shadow: 0 14px 40px rgba(24,32,38, .16) !important;
  padding: 8px !important;
}

.option-popover button {
  justify-content: space-between;
  text-align: left;
}


/* 拖动节点时的吸附对齐辅助线 */
.snap-guide {
  position: fixed;
  z-index: 38;
  pointer-events: none;
  background: rgba(82, 109, 245, .55);
}

.snap-guide-v {
  top: 0;
  bottom: 0;
  width: 1px;
}

.snap-guide-h {
  left: 0;
  right: 0;
  height: 1px;
}

/* 端口尺寸跟随画布缩放，刻意不做反向补偿。
   这里原本是 zoom: var(--node-zoom, 1)（画布越小把手越大），把端口钉在固定屏幕尺寸上：
   缩到 0.5 时圆点仍有 22px / 30px，在缩小的画布上显得过大，磁吸圈也够得太远。
   去掉之后：最小缩放 22px→11px、30px→15px（正好一半），最大缩放 44px / 60px（不变）。 */

/* 文本节点：无框 + 二级菜单（左：API平台/文本模型，右：运行） */
.text-node .compact-stage {
  aspect-ratio: auto;
  min-height: 190px;
  padding: 10px 12px;
}

.text-node-out {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 7;
  overflow: hidden;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12px;
  line-height: 1.6;
  color: #171a1d;
  text-align: left;
}

.text-node .compact-toolbar {
  flex-wrap: wrap;
}

.text-node .compact-toolbar .compact-run {
  margin-left: auto;
}

.text-node .node-api-select-row select,
.text-model-select {
  min-width: 0;
}

/* 大图预览：全屏深色无框，滚轮无级缩放，右上控制条（参考统一 UI） */
.image-preview-overlay {
  background: rgba(23, 26, 29, .9) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  padding: 0 !important;
  display: block !important;
  overflow: hidden !important;
}

.image-preview-card {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  display: flex !important;
  flex-direction: column !important;
  overflow: visible !important;
  animation: none !important;
}

.image-preview-bar {
  position: absolute;
  top: 18px;
  right: 22px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, .95);
  border-radius: var(--ai2-r-panel);
  padding: 6px 10px;
  box-shadow: 0 10px 30px rgba(24,32,38, .16);
}

.image-preview-name {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 700;
  color: #667078;
  padding: 0 4px;
}

.image-preview-btn {
  border: none;
  background: #edeff2;
  color: #33383d;
  border-radius: var(--ai2-r-field);
  min-width: 30px;
  height: 30px;
  padding: 0 10px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  font-family: inherit;
  line-height: 1;
}

.image-preview-btn:hover {
  background: #ccd3d9;
}

.image-preview-btn.primary {
  background: #171a1d;
  color: #fff;
}

.image-preview-btn.close {
  background: #526df5;
  color: #fff;
}

.image-preview-pct {
  min-width: 46px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  color: #33383d;
}

.image-preview-stage {
  flex: 1 1 auto;
  overflow: visible !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  background: transparent !important;
  place-items: unset;
}

.image-preview-stage img {
  max-width: none !important;
  max-height: none !important;
  width: auto !important;
  height: auto !important;
  /* 预览就是「放大看原始像素」，图片本身是直角，放大后不能带圆角（宫格切出来的小图尤其明显）。 */
  border-radius: 0 !important;
  box-shadow: 0 30px 80px rgba(24,32,38, .16);
  cursor: grab;
  pointer-events: auto;
}

.image-preview-stage img:active {
  cursor: grabbing;
}

/* API 设置左侧平台/工作流列表：独立滚动 + 细滚动条（滚轮滚动、按住滑块拖动） */
.platform-list {
  overflow-y: auto;
  max-height: min(66vh, 540px);
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: #ccd3d9 transparent;
}

.platform-list::-webkit-scrollbar {
  width: 6px;
}

.platform-list::-webkit-scrollbar-thumb {
  background: #ccd3d9;
  border-radius: 999px;
}

.platform-list::-webkit-scrollbar-thumb:hover {
  background: #ccd3d9;
}

.platform-list::-webkit-scrollbar-track {
  background: transparent;
}

/* API 设置左侧 RunningHub 工作流卡片 */
.rh-side-title {
  margin-top: 12px;
}

.rh-wf-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.platform-list button .rh-wf-name {
  text-align: left;
}

/* RunningHub 工作流编辑器 */
.rh-wf-path {
  font-size: 11px;
  color: #9aa2a9;
  background: #f7f8fa;
  border-radius: var(--ai2-r-tag);
  padding: 5px 9px;
  font-family: Consolas, monospace;
}

.rh-note-input {
  width: 100%;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  padding: 8px 10px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
  color: #171a1d;
  resize: vertical;
  outline: none;
}

.rh-note-input:focus {
  border-color: #526df5;
}

.settings-form .rh-param-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  color: #667078;
  margin: 4px 0 6px;
}

/* 所有节点无外框（分组节点除外）；选中只在节点内容上显示一圈高亮，不再有外层线框 */
.node-shell:not(.group-node) {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

.node-shell.selected:not(.group-node) {
  outline: none;
}

.node-shell.selected:not(.group-node) .compact-stage {
  box-shadow: 0 0 0 2px rgba(82, 109, 245, .18);
}

/* 空白图片节点：文字放底部，与居中上传图标分离 */
.compact-placeholder.compact-placeholder-textonly {
  place-items: end center;
  align-content: end;
  padding-bottom: 12px;
}

/* 图片节点：有图时去掉外框，图片铺满节点（参考无边框样式） */
.bare-image-node.has-image {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

.bare-image-node.has-image .compact-stage {
  border-radius: var(--ai2-r-field);
}

.bare-image-node.has-image.selected .compact-stage {
  box-shadow: 0 0 0 2px rgba(82, 109, 245, .18);
}

/* 空白图片节点：居中的本地上传图标。投影和白底圆圈都去掉，只留图标本身
   （命中区域仍是 46px，hover 才有底色反馈）。 */
.compact-upload-overlay.centered {
  top: 50%;
  left: 50%;
  right: auto;
  transform: translate(-50%, -50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: transparent;
  box-shadow: none;
}

.node-shell .compact-upload-overlay.centered:hover {
  background: transparent !important;
  color: #667078 !important;
  transform: translate(-50%, -50%) scale(1.08);
}

.bare-image-caption {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 2px 4px;
  font-size: 11px;
  color: #9aa2a9;
  max-width: 100%;
}

.bare-image-caption span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.compact-pill select {
  appearance: none;
  border: 0;
  background: transparent;
  color: #667078;
  font-size: 12px;
  font-weight: 700;
  font-family: inherit;
  outline: none;
  cursor: pointer;
  padding: 0 2px;
  max-width: 52px;
}

.compact-run {
  margin-left: auto;
  margin-right: 2px;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: 50%;
  background: #171a1d;
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 0.14s ease, transform 0.12s ease;
}

.compact-run:hover:not(:disabled) {
  background: #526df5;
  transform: translateY(-1px);
}

.compact-run:active:not(:disabled) {
  transform: translateY(0) scale(0.97);
}

.compact-run:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.compact-size-popover {
  position: absolute;
  right: 14px;
  bottom: 112px;
  width: min(420px, calc(100% - 56px));
  padding: 18px;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  border: 1px solid #e3e7ea;
  box-shadow: 0 18px 50px rgba(24,32,38, .16);
  z-index: 100;
}

.compact-popover-title {
  margin: 8px 0 6px;
  font-size: 11px;
  font-weight: 700;
  color: #667078;
}

.compact-popover-title:first-child {
  margin-top: 0;
}

.compact-size-popover .option-popover {
  position: static;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  max-height: none;
  overflow: visible;
}

.compact-size-popover .option-popover button {
  height: 34px;
  border-radius: var(--ai2-r-field);
  background: #f1f3f5;
  color: #667078;
  font-size: 12px;
}

.compact-size-popover .option-popover button.active {
  background: #eef1ff;
  color: #3f55c4;
}

.compact-panel > .option-popover {
  position: relative;
  left: auto;
  top: auto;
  transform: none;
  width: 100%;
  margin: 18px 0 0;
  padding: 14px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  background: #fff;
  box-shadow: 0 18px 50px rgba(24,32,38, .16);
  max-height: 190px;
  overflow: auto;
}

/* @ 引用弹层：可引用项横排、放不下自动换行（标题独占一行）。
   原来是块级堆叠，三张上游图就竖着排满 150px 还滚出滚动条。 */
.compact-mention {
  position: absolute;
  left: 28px;
  right: 28px;
  bottom: 128px;
  z-index: 95;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px;
  max-height: 150px;
  overflow-y: auto;
  padding: 12px;
  border-radius: var(--ai2-r-field);
  background: #fff;
  border: 1px solid #e3e7ea;
  box-shadow: 0 18px 50px rgba(24,32,38, .16);
}

.compact-hidden-control {
  display: none !important;
}

.video-node.compact-node .ai2-imported-video-preview {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .compact-stage,
  .compact-icon-btn,
  .compact-pill,
  .compact-run {
    transition: none !important;
  }
}

body.node-dragging .compact-panel,
body.node-dragging .compact-top,
body.node-dragging .compact-mention,
body.node-dragging .compact-size-popover {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.compact-panel,
.compact-top,
.compact-mention,
.compact-size-popover {
  transition: opacity 0.14s ease, visibility 0.14s ease;
}

@media (prefers-reduced-motion: reduce) {
  .compact-panel,
  .compact-top,
  .compact-mention,
  .compact-size-popover {
    transition: none !important;
  }
}

.node-shell {
  border-radius: var(--ai2-r-node);
}

.generate-node:not(.compact-node),
.video-node:not(.compact-node),
.upscale-node,
.reverse-node {
  border-radius: var(--ai2-r-node);
}

.group-node {
  border-radius: var(--ai2-r-node);
}

/* Unified corner system: one radius for panels, fields and controls. */
:root {
  --ai2-radius: 24px;
}

#root :where(
  button,
  input,
  select,
  textarea,
  .node-shell,
  .node-textarea,
  .image-frame,
  .empty-preview,
  .preview-thumb,
  .compact-stage,
  .compact-top,
  .compact-panel,
  .compact-toolbar .node-api-select-row,
  .compact-pill,
  .compact-size-popover,
  .compact-panel > .option-popover,
  .compact-mention,
  .context-menu,
  .option-popover,
  .option-popover-head,
  .top-toolbar,
  .left-panel,
  .settings-panel,
  .settings-header button,
  .run-log-panel,
  .image-preview-card,
  .gen-expand-panel,
  .gen-expand-textarea,
  .gen-expand-preview,
  .minimap
) {
  border-radius: var(--ai2-radius) !important;
}

#root :where(
  .compact-icon-btn,
  .compact-upload-overlay,
  .compact-running,
  .compact-run,
  .preview-thumb-remove,
  .dot,
  .react-flow__handle
) {
  border-radius: 50% !important;
}

#ai2-canvas-history-root :where(
  button,
  input,
  select,
  textarea,
  .ai2-canvas-panel,
  .ai2-history-item,
  .ai2-history-thumb,
  .ai2-status,
  .ai2-empty
) {
  border-radius: var(--ai2-radius) !important;
}

#ai2-canvas-history-root .ai2-canvas-close {
  border-radius: 50% !important;
}


/* 图片节点尺寸/清晰度弹层（专属）：网格布局、浅紫选中 */
.compact-toolbar .compact-pill > .compact-size-popover .option-popover {
  position: static !important;
  width: 100% !important;
  min-width: 0 !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  max-height: none !important;
  overflow: visible !important;
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 8px !important;
}

.compact-toolbar .compact-pill > .compact-size-popover .option-popover button {
  height: 34px !important;
  border-radius: var(--ai2-r-field) !important;
  background: #f1f3f5 !important;
  color: #667078 !important;
  font-size: 12px !important;
  justify-content: center !important;
  text-align: center !important;
  padding: 0 8px !important;
  border: none !important;
}

.compact-toolbar .compact-pill > .compact-size-popover .option-popover button:hover {
  background: #eef1ff !important;
  color: #3f55c4 !important;
}

.compact-toolbar .compact-pill > .compact-size-popover .option-popover button.active {
  background: #eef1ff !important;
  color: #3f55c4 !important;
  font-weight: 700;
}

/* Warm peach control system: readable secondary buttons with outlined selection. */
.compact-toolbar {
  gap: 10px !important;
}

.compact-toolbar .node-api-select-row,
.compact-pill,
.gen-tool-pill {
  min-height: 44px !important;
  height: 44px !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-field) !important;
  background: #fff !important;
  color: #667078 !important;
  padding: 0 16px !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  transition: background .18s ease, border-color .18s ease, color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.compact-toolbar .node-api-select-row:hover,
.compact-pill:hover,
.gen-tool-pill:hover {
  background: #fff !important;
  border-color: #8e9bf9 !important;
  color: #3f55c4 !important;
  transform: translateY(-1px);
}

.compact-pill.active,
.gen-tool-pill.active,
.compact-toolbar .node-api-select-row:focus-within {
  background: #fff !important;
  border: 2px solid #526df5 !important;
  color: #3f55c4 !important;
  box-shadow: inset 0 0 0 3px #eef1ff !important;
}

.compact-pill.active span,
.gen-tool-pill.active span,
.compact-pill.active .select-label,
.compact-pill.active .select-val,
.compact-pill.active .select-arrow {
  color: #3f55c4 !important;
}

.compact-run,
.gen-tool-run,
.run-pill {
  min-width: 46px !important;
  min-height: 46px !important;
}

/* Third-level controls stay attached to the clicked second-level pill and open upward. */
.compact-toolbar .compact-pill > .option-popover,
.compact-toolbar .compact-pill > .compact-size-popover,
.compact-toolbar .gen-tool-pill > .option-popover,
.compact-toolbar .gen-tool-pill > .compact-size-popover {
  position: absolute !important;
  left: 0 !important;
  right: auto !important;
  top: auto !important;
  bottom: calc(100% + 26px) !important;
  transform: none !important;
  z-index: 120 !important;
}

.compact-toolbar .compact-pill > .option-popover,
.compact-toolbar .gen-tool-pill > .option-popover {
  width: max-content !important;
  min-width: 210px !important;
  max-width: min(420px, calc(100vw - 32px)) !important;
  max-height: 320px !important;
  overflow-y: auto !important;
  padding: 8px !important;
  gap: 6px !important;
  border: 1px solid #ccd3d9 !important;
  border-radius: var(--ai2-r-field) !important;
  background: #fff !important;
  box-shadow: 0 18px 42px rgba(82, 109, 245, .18) !important;
}

.compact-toolbar .compact-pill > .option-popover button,
.compact-toolbar .gen-tool-pill > .option-popover button {
  min-height: 44px !important;
  height: 44px !important;
  border: 1px solid transparent !important;
  border-radius: var(--ai2-r-field) !important;
  background: #f7f8fa !important;
  color: #667078 !important;
  padding: 0 16px !important;
  justify-content: center !important;
  text-align: center !important;
  font-size: 13px !important;
}

.compact-toolbar .compact-pill > .option-popover button:hover,
.compact-toolbar .compact-pill > .option-popover button.active,
.compact-toolbar .gen-tool-pill > .option-popover button:hover,
.compact-toolbar .gen-tool-pill > .option-popover button.active {
  background: #fff !important;
  border-color: #526df5 !important;
  color: #3f55c4 !important;
  box-shadow: inset 0 0 0 2px #eef1ff !important;
}

/* Size is a grouped third-level panel: complete quality, ratio, and count controls. */
.compact-toolbar .compact-pill > .compact-size-popover,
.compact-toolbar .gen-tool-pill > .compact-size-popover {
  width: min(680px, calc(100vw - 32px)) !important;
  max-width: min(680px, calc(100vw - 32px)) !important;
  padding: 16px !important;
  border: 1px solid #ccd3d9 !important;
  border-radius: var(--ai2-r-panel) !important;
  background: #fff !important;
  box-shadow: 0 18px 42px rgba(82, 109, 245, .18) !important;
}

.compact-size-popover .compact-popover-title {
  margin: 2px 0 10px !important;
  color: #667078 !important;
  font-size: 14px !important;
  font-weight: 700 !important;
}

.compact-size-popover .option-popover {
  position: static !important;
  width: 100% !important;
  min-width: 0 !important;
  max-width: none !important;
  max-height: none !important;
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 10px !important;
  margin: 0 0 14px !important;
  padding: 0 !important;
  overflow: visible !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.compact-size-popover .option-popover:last-child {
  margin-bottom: 0 !important;
}

.compact-size-popover .option-popover button {
  min-height: 48px !important;
  height: 48px !important;
  border-radius: var(--ai2-r-field) !important;
  border: 1px solid transparent !important;
  background: #f7f8fa !important;
  color: #667078 !important;
  font-size: 13px !important;
}

.compact-size-popover .option-popover button:hover,
.compact-size-popover .option-popover button.active {
  background: #fff !important;
  border-color: #526df5 !important;
  color: #3f55c4 !important;
  box-shadow: inset 0 0 0 2px #eef1ff !important;
}

.compact-size-popover .ratio-option-inner {
  gap: 8px !important;
}

@media (max-width: 700px) {
  .compact-size-popover .option-popover {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* 生成节点的三级菜单挂在独立容器中，也要从二级工具条上方弹出。 */
.gen-expand-panel {
  overflow: visible !important;
}

.gen-expand-popovers:not(:empty) {
  position: absolute !important;
  left: 20px !important;
  right: 20px !important;
  bottom: 98px !important;
  z-index: 120 !important;
  padding: 0 !important;
  pointer-events: none;
}

.gen-expand-popovers:not(:empty) .option-popover {
  position: relative !important;
  width: 100% !important;
  margin: 0 !important;
  pointer-events: auto;
}

/* 尺寸三级菜单只保留选项，隐藏分组文案并保留两组之间的呼吸感。 */
.compact-size-popover .compact-popover-title {
  display: block !important;
}

.compact-size-popover .option-popover {
  row-gap: 14px !important;
  margin-bottom: 28px !important;
}

/* 尺寸三级菜单完整展示：外层不截断内容，也不显示滚动轨道。 */
.compact-node .compact-pill > .compact-size-popover,
.compact-toolbar .compact-pill > .compact-size-popover,
.compact-toolbar .gen-tool-pill > .compact-size-popover {
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  overflow: visible !important;
  scrollbar-width: none !important;
  padding: 18px !important;
}

.compact-panel .compact-textarea,
.gen-expand-textarea,
.node-textarea {
  border-color: #e3e7ea !important;
}

/* 输入框下的二级选项统一贴近输入框，仅保留小间隙。 */
.compact-panel > .compact-toolbar {
  margin-top: 10px !important;
}

.gen-expand-panel > .gen-expand-toolbar {
  padding-top: 10px !important;
}

.generate-node .node-option-wrap,
.upscale-node .node-option-wrap,
.reverse-node .node-option-wrap {
  margin-top: 10px !important;
}

/* 全局暖桃色状态：覆盖旧版紫色 hover/focus/active 规则。 */
.compact-upload-overlay:hover,
.compact-icon-btn:hover:not(:disabled),
.compact-pill:hover,
.compact-pill.active,
.compact-size-popover .option-popover button:hover,
.compact-size-popover .option-popover button.active,
.compact-toolbar .compact-pill > .option-popover button:hover,
.compact-toolbar .compact-pill > .option-popover button.active,
.compact-toolbar .gen-tool-pill > .option-popover button:hover,
.compact-toolbar .gen-tool-pill > .option-popover button.active {
  background: #eef1ff !important;
  color: #3f55c4 !important;
}

.compact-textarea:focus,
.rh-node-input:focus,
.compact-toolbar .node-api-select-row:focus-within {
  border-color: #8e9bf9 !important;
  box-shadow: 0 0 0 3px rgba(82, 109, 245, .22) !important;
}

.compact-run:hover:not(:disabled),
.multi-sel-plus:hover {
  background: #eef1ff !important;
  color: #3f55c4 !important;
}

.platform-list button.dragging,
.platform-list button.drag-over {
  outline-color: #8e9bf9 !important;
  background: #eef1ff !important;
}

.rh-field-idx {
  color: #3f55c4 !important;
}

/* ==========================================================================
   图片节点多图：节点内叠放（收起态）与两行宫格（展开态）。
   收起态：主图在最上层，其余图片作为后置卡片向左上/右下交替叠放并降低清晰度。
   展开态：outputImages 全部进入固定两行宫格，列数 = ceil(图片数 / 2)，
           第一列与主图左边缘对齐，按图片数量向右扩展。
   数据侧只读 outputImages，选图只写 image —— 这一层全是视图。
   ========================================================================== */

.image-node.compact-node {
  position: relative !important;
}

/* 叠图整层不吃指针事件：点击、拖拽、上传仍然落在原有的 .compact-stage 上。 */
.multi-image-stack {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}

.multi-image-card {
  position: absolute;
  inset: 0;
  display: block;
  border-radius: inherit;
  transform-origin: 50% 50%;
}

/* 主图永远压在叠图最上层，放大、下载、alt 和比例逻辑都还在这张图上。 */
.multi-image-stack .multi-image-card.is-current {
  z-index: 2;
}

/* 后置卡片：和主图同心，只有旋转 + 缩放，不做位移（主图位置永远不动）。
   固定两层：b 右转、c 左转，左右对称扇形摊在主图后面；再多图片也不加层。
   模糊只作用在卡片里的 img 上——卡片本身的圆角、描边和投影保持清晰，
   内容糊掉、整体压暗一点，看起来像压在下面的一摞照片。 */
.multi-image-stack .multi-image-card.is-back {
  z-index: 1;
  overflow: hidden;
  border: 1px solid var(--ai2-border, #e3e7ea);
  background: var(--ai2-surface-2, #f7f8fa);
  box-shadow: 0 10px 26px rgba(24, 32, 38, .16);
  transition: transform 180ms cubic-bezier(.22, .8, .25, 1), opacity 180ms cubic-bezier(.22, .8, .25, 1);
}

.multi-image-stack .multi-image-card.is-back img {
  filter: blur(5px) brightness(.9) saturate(.94);
}

.multi-image-stack .multi-image-card.is-back[data-stack-depth="1"] {
  transform: rotate(10deg) scale(.96);
  opacity: .5;
}

.multi-image-stack .multi-image-card.is-back[data-stack-depth="2"] {
  transform: rotate(-10deg) scale(.92);
  opacity: .5;
}

.multi-image-stack .multi-image-card.is-back[data-stack-depth="2"] img {
  filter: blur(7px) brightness(.84) saturate(.92);
}

/* 后置卡片要露在主图外面，所以只有带叠图的多图节点放开 stage 的裁切。
   卡片本身 border-radius: inherit，主图圆角不受影响。 */
.image-node.compact-node .compact-stage:has(> .multi-image-stack.has-stack) {
  overflow: visible;
}

/* 宫格铺满媒体区并向右延伸，但连线端口必须留在卡片之上，
   否则开着宫格就拖不出连线（仍低于工具条 80 / 面板 90）。 */
.image-node.compact-node .react-flow__handle {
  z-index: 70;
}

/* 宫格向上铺开会盖到节点标题带上，标题是贴在图上的浮动文案，浏览大图时先让开
   （工具条留着——多图入口在那儿，用户要能随时收起）。 */
.image-node.ai2-gallery-open > .node-header {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.14s ease, visibility 0.14s ease;
}

/* 进入叠图：后置卡片从原位淡入到最终偏移，主图保持不动。
   fill 用 backwards 而不是 both —— 收尾后不再钉住属性，后续换主图才能走过渡。 */
@keyframes ai2-multi-stack-in {
  from {
    opacity: 0;
    transform: translate(0, 0) scale(.98);
    filter: blur(0);
  }
}

.multi-image-stack.has-stack .multi-image-card.is-back {
  animation: ai2-multi-stack-in 180ms cubic-bezier(.22, .8, .25, 1) backwards;
}

/* 切换主图：新主图从当前位置轻微抬起（旧主图同时退成后置层）。 */
@keyframes ai2-multi-promote {
  from {
    opacity: .55;
    transform: scale(.96);
  }
}

.multi-image-stack.has-stack .multi-image-card.is-current {
  animation: ai2-multi-promote 180ms cubic-bezier(.22, .8, .25, 1) backwards;
}

/* 展开态宫格：单元格和主图一样大（不是缩略图，也没有任何底板/边框/背景）。
   宫格左下角就落在媒体区左下角——主图那一格原地不动，其余向右、向上摊开。
   宽度按列数算、不设上限：列数多的时候允许整块继续长出去（画布可以平移缩放），
   绝不靠压缩单元格来迁就视口，否则格子会比主图小、还会盖在主图上。 */
.multi-image-gallery {
  --multi-image-cell-ratio: 100%;
  --multi-image-gap: 12px;
  --multi-image-cols: 1;
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 60;
  box-sizing: border-box;
  width: calc(var(--multi-image-cell-ratio) * var(--multi-image-cols) + var(--multi-image-gap) * (var(--multi-image-cols) - 1));
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  /* 右侧空间不足时横向滚动，既不压缩单元格也不改节点布局尺寸。 */
  overflow-x: auto;
  overflow-y: hidden;
  transition: opacity 0.14s ease, visibility 0.14s ease;
}

.multi-image-grid {
  display: grid;
  grid-template-columns: repeat(var(--multi-image-cols, 1), minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: var(--multi-image-gap);
}

/* 单元格：统一宽高比 + cover 大图；主图排在第一格（左下角，就是它原来的位置，不动），
   其余按 outputImages 顺序向右、向上铺开。卡片本身就是一张图，没有底板没有边框。
   aspect-ratio 必须留在卡片上：宫格容器高度是 auto，两行的高度只能由卡片的
   固有宽高比推出来（--multi-image-cell-aspect 由节点当前比例写成）。 */
.multi-image-grid .multi-image-card {
  position: relative;
  inset: auto;
  min-width: 0;
  padding: 0;
  aspect-ratio: var(--multi-image-cell-aspect, 1 / 1);
  border: 0;
  border-radius: var(--ai2-r-field, 14px);
  background: var(--ai2-surface-2, #f7f8fa);
  box-shadow: 0 12px 30px rgba(24, 32, 38, .2);
  cursor: pointer;
  overflow: hidden;
  /* 摊开动效：从主图原位（左上那格）沿直线飞到自己格子，带一点初始旋转。 */
  animation: ai2-multi-spread 260ms cubic-bezier(.22, .8, .25, 1) backwards;
  animation-delay: min(calc(var(--multi-image-index, 0) * 24ms), 180ms);
}

@keyframes ai2-multi-spread {
  from {
    transform: translate(calc(-100% * var(--multi-image-spread-x, 0) - var(--multi-image-gap) * var(--multi-image-spread-x, 0)), calc(100% * var(--multi-image-spread-y, 0) + var(--multi-image-gap) * var(--multi-image-spread-y, 0))) rotate(var(--multi-image-spread-rotate, -12deg)) scale(.9);
    /* 起点全透明：摊开时是「从叠放位置长出来」，收起倒放时也是彻底消失，
       不会像之前那样以半透明停在主图上（那一下就是用户看到的闪烁）。 */
    opacity: 0;
  }
}

/* 摊开/收回的动效按上一版来：所有格子（含主图那格）都参与，不做例外。
   主图那格的偏移量本来就是 0，所以它只是跟着轻微旋转缩放落位，位置不会跑掉。 */
.multi-image-gallery.is-closing .multi-image-grid .multi-image-card {
  animation: ai2-multi-spread 180ms cubic-bezier(.22, .8, .25, 1) reverse forwards;
  animation-delay: 0ms;
}

/* 收起时整块宫格同时淡出兜底：即使有的帧没跟上，也不会留下半透明的卡片盖在主图上。 */
.multi-image-gallery.is-closing {
  opacity: 0;
  transition: opacity 160ms ease-out;
}

/* 宫格摊开期间，收起态的叠放层先让位——否则那两张斜着的卡片会从宫格边上露出来
   （就是展开后旁边多出来的那道彩边）。 */
.image-node.ai2-gallery-open .multi-image-stack .multi-image-card.is-back {
  opacity: 0;
  transition: opacity 140ms ease;
}

.multi-image-grid .multi-image-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  pointer-events: none;
}

/* 悬停/键盘聚焦只加一圈细描边，不动投影（卡片本身就是图，别糊成一团）。 */
.multi-image-grid .multi-image-card:hover,
.multi-image-grid .multi-image-card:focus-visible {
  outline: 2px solid var(--ai2-accent-line, #c3ccfb);
  outline-offset: -2px;
}

/* 当前主图：描边 + 角标，两重提示不只靠颜色。 */
.multi-image-grid .multi-image-card.is-current {
  outline: 2px solid var(--ai2-accent, #526df5);
  outline-offset: -2px;
  box-shadow: 0 12px 30px rgba(82, 109, 245, .28);
}

/* 生成中不允许误选旧图片。 */
.multi-image-grid .multi-image-card:disabled {
  cursor: not-allowed;
  opacity: .6;
}

.multi-image-current-mark {
  position: absolute;
  right: 4px;
  bottom: 4px;
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ai2-accent, #526df5);
  color: #fff;
  font-size: 10px;
  line-height: 1;
  pointer-events: none;
}

/* 拖节点时宫格跟工具条一起让开，避免浮在画布上被误点。 */
body.node-dragging .multi-image-gallery {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* 裁剪期间和工具条、编辑面板一样隐藏，不抢交互。 */
.image-node.ai2-cropping > .multi-image-gallery {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* 减少动态效果：取消位移、缩放、模糊渐变和错峰延迟，只留静态叠放与选中描边。 */
@media (prefers-reduced-motion: reduce) {
  .multi-image-stack .multi-image-card.is-back,
  .multi-image-stack .multi-image-card.is-current,
  .multi-image-gallery,
  .multi-image-grid .multi-image-card,
  .image-node.ai2-gallery-open > .node-header {
    animation: none !important;
    transition: none !important;
    animation-delay: 0ms !important;
  }
}

/* 参考图排序：被拖的那颗自己贴着指针走（transform 由脚本写），只给它抬层级 + 描边投影。
   原来的虚线占位框和克隆残影一起去掉了。 */
.preview-row.is-upstream-dragging { cursor: grabbing; }
.preview-thumb.is-upstream-dragging { cursor: grabbing; z-index: 30; }
.preview-row .preview-thumb { touch-action: pan-y; user-select: none; }
.preview-thumb.ai2-upstream-drag-ghost {
  outline: 2px solid #526df5;
  border-radius: var(--ai2-r-field);
  box-shadow: 0 12px 26px rgba(82, 109, 245, .22);
  will-change: transform;
}

/* 提示词中的“图N”以内联缩略图显示，输入仍由原生 textarea 处理。 */
.ai2-inline-mention-layer {
  position: absolute;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
  color: #171a1d;
  background: transparent;
  white-space: pre-wrap;
  word-wrap: break-word;
  user-select: none;
}

.ai2-inline-mention-layer[hidden] {
  display: none !important;
}

.ai2-inline-mention-token {
  display: inline-flex;
  width: 1.2em;
  height: 1.2em;
  margin: 0 .12em;
  vertical-align: -.22em;
  border-radius: .28em;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(82, 109, 245, .22);
}

.ai2-inline-mention-token img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

textarea.ai2-inline-mention-active {
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
  background: transparent !important;
  caret-color: #3f55c4 !important;
}

/* ==========================================================================
   图片节点画笔工具：一行工具条贴在图片下方
   （退出 | 颜色组 | 笔刷大小 | 撤销 清空 | 确定），布局照参考稿的分段图标工具条，
   配色和圆角跟画布走。
   ========================================================================== */

/* 工具条挂在 body 上、fixed 定位：不随画布缩放放大，位置由 JS 每帧贴着图片框算。 */
.ai2-paint-popover {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 260;
  display: flex;
  align-items: center;
  gap: 6px;
  width: max-content;
  max-width: calc(100vw - 16px);
  padding: 6px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  box-shadow: 0 18px 44px rgba(82, 109, 245, .16);
  transform: translateX(-50%);
  pointer-events: auto;
}

.ai2-paint-popover[hidden] {
  display: none;
}

.ai2-paint-divider {
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: #e3e7ea;
}

/* 退出：✕ + 工具名，点击即放弃本次涂鸦。 */
.ai2-paint-back {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 32px;
  padding: 0 10px;
  border: none;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #667078;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
}

.ai2-paint-back:hover {
  background: #f7f8fa;
  color: #171a1d;
}

/* 工具组：画笔 / 框选 / 箭头 / 文字。条是白的，所以组内垫一层米白成组。 */
.ai2-paint-tools {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--ai2-r-field);
  background: #f7f8fa;
}

.ai2-paint-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #667078;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}

.ai2-paint-tool:hover {
  background: #fff;
  color: #171a1d;
}

.ai2-paint-tool.active {
  background: #171a1d;
  color: #fff;
}

/* 颜色：条上只放当前色那颗点 + 箭头，点开四级色板。 */
.ai2-paint-color {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #9aa2a9;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}

.ai2-paint-color:hover {
  background: #f7f8fa;
}

.ai2-paint-color[aria-expanded="true"] {
  border-color: #e3e7ea;
  background: #f7f8fa;
}

/* 画笔取色点的默认色属于「内容色」不是界面色，视觉改造不动它（运行时会由所选颜色覆盖）。 */
.ai2-paint-color-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #ef4444;
  box-shadow: 0 0 0 1px #e3e7ea;
}

/* 四级色板：横向一排，居中对齐颜色按钮（JS 会写 left 做视口内收）。 */
.ai2-paint-palette {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  box-shadow: 0 14px 32px rgba(82, 109, 245, .12);
  transform: translateX(-50%);
  pointer-events: auto;
}

.ai2-paint-palette[hidden] {
  display: none;
}

/* 工具条贴底时色板朝上展开。 */
.ai2-paint-palette-up {
  top: auto;
  bottom: calc(100% + 12px);
}

.ai2-paint-swatch {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 1px #e3e7ea;
  cursor: pointer;
  transition: transform 0.14s ease;
}

.ai2-paint-swatch:hover {
  transform: scale(1.12);
}

.ai2-paint-swatch.selected {
  box-shadow: 0 0 0 2px #171a1d;
}

/* 自定义取色：只露出圆形取色口，彩虹底表示"任意颜色"。 */
.ai2-paint-custom {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  width: 22px;
  height: 22px;
  overflow: hidden;
  border-radius: 50%;
  box-shadow: 0 0 0 1px #e3e7ea;
  cursor: pointer;
}

.ai2-paint-custom.selected {
  box-shadow: 0 0 0 2px #171a1d;
}

.ai2-paint-custom input {
  width: 34px;
  height: 34px;
  margin: -6px;
  padding: 0;
  border: 0;
  background: conic-gradient(#ef4444, #eab308, #22c55e, #06b6d4, #3b82f6, #8b5cf6, #ef4444);
  cursor: pointer;
}

/* 出错时就地在工具条上方提示，不弹窗。 */
.ai2-paint-error {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  z-index: 3;
  max-width: min(420px, calc(100vw - 24px));
  padding: 6px 12px;
  border: 1px solid #ccd3d9;
  border-radius: var(--ai2-r-field);
  background: #fff;
  color: #c23a44;
  font-size: 12px;
  line-height: 1.4;
  text-align: center;
  box-shadow: 0 10px 26px rgba(82, 109, 245, .12);
  transform: translateX(-50%);
  pointer-events: none;
}

.ai2-paint-error[hidden] {
  display: none;
}

/* 文字工具的就地输入框。 */
.ai2-paint-text-input {
  position: fixed;
  z-index: 262;
  width: 190px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  background: #fff;
  color: #171a1d;
  font-size: 12px;
  line-height: 1;
  outline: none;
  box-shadow: 0 10px 26px rgba(82, 109, 245, .16);
}

.ai2-paint-text-input:focus-visible,
.ai2-paint-tool:focus-visible,
.ai2-paint-color:focus-visible {
  outline: 2px solid #526df5;
  outline-offset: 1px;
}

/* 笔刷大小：滑杆 + 数值读数。 */
.ai2-paint-size {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 4px;
  color: #667078;
  font-size: 11px;
}

.ai2-paint-size input {
  width: 108px;
  accent-color: #526df5;
  cursor: pointer;
}

.ai2-paint-size output {
  min-width: 20px;
  color: #33383d;
  font-weight: 600;
  text-align: right;
}

/* 撤销 / 清空：图标按钮。 */
.ai2-paint-undo,
.ai2-paint-clear {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #667078;
  cursor: pointer;
}

.ai2-paint-undo:hover,
.ai2-paint-clear:hover {
  background: #f7f8fa;
  color: #171a1d;
}

.ai2-paint-undo:focus-visible,
.ai2-paint-clear:focus-visible,
.ai2-paint-swatch:focus-visible,
.ai2-paint-back:focus-visible {
  outline: 2px solid #526df5;
  outline-offset: 1px;
}

/* 确定：沿用画布的深色主按钮。 */
.ai2-paint-confirm {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 60px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid #171a1d;
  border-radius: var(--ai2-r-field);
  background: #171a1d;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.ai2-paint-confirm:hover {
  background: #171a1d;
  border-color: #171a1d;
}

.ai2-paint-trigger { font-size: 16px; line-height: 1; }

/* 涂鸦层铺在图片上；工具条在节点外层可见，所以节点不能裁掉溢出。 */
.compact-stage { position: relative !important; }
.image-node.compact-node.ai2-painting { z-index: 240; overflow: visible !important; }
.image-node.ai2-painting { position: relative !important; }
.ai2-painting .compact-stage { z-index: 2; }
.ai2-paint-canvas {
  position: absolute;
  z-index: 4;
  inset: 0;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  pointer-events: auto;
  cursor: crosshair;
  touch-action: none;
}

@media (max-width: 900px) {
  .ai2-paint-popover {
    border-radius: var(--ai2-r-panel);
  }

  .ai2-paint-size input {
    width: 72px;
  }
}

/* 生成图片节点的尺寸只取橙色图片框；标题与像素信息悬浮在框外，不参与节点高度。
   标题行和顶部工具条都是 bottom: 100% + 一点，处在同一条横向带里会互相压住。
   标题行贴着图片不动，工具条往上抬，让开「标题行间距 + 标题行高 + 自己的间距」。 */
.bare-image-node {
  position: relative !important;
  padding: 0 !important;
  --ai2-header-gap: 8px;
  --ai2-header-height: 28px;
  --ai2-toolbar-gap: 10px;
}
.bare-image-node > .node-header {
  position: absolute !important;
  left: 0 !important;
  right: 0 !important;
  bottom: calc(100% + var(--ai2-header-gap)) !important;
  margin: 0 !important;
  pointer-events: none !important;
  z-index: 240 !important;
}
.bare-image-node > .compact-stage {
  width: 100% !important;
}
/* 二级菜单的位置：不管有没有图，都让开「标题行间距 + 标题行高 + 自己的间距」，
   空节点和有图节点的工具条落在同一条高度上。 */
.bare-image-node > .compact-top {
  bottom: calc(100% + var(--ai2-header-gap) + var(--ai2-header-height) + var(--ai2-toolbar-gap)) !important;
}

/* ==========================================================================
   图片节点裁剪工具（ai2-crop- 命名空间，仅追加，不覆盖既有规则）
   ========================================================================== */

.ai2-crop-trigger {
  display: grid;
  place-items: center;
  color: #33383d;
}

.image-node.compact-node.ai2-cropping {
  position: relative !important;
  overflow: visible !important;
  z-index: 250;
}

/* 裁剪期间隐藏普通工具条与编辑面板的交互，但不删除 React 创建的 DOM。 */
.image-node.ai2-cropping > .compact-top,
.image-node.ai2-cropping > .compact-panel {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

/* 进入裁剪后完整显示原图，避免 cover 裁掉边缘。 */
.image-node.ai2-cropping .compact-stage img {
  object-fit: contain;
}

.ai2-crop-overlay {
  position: absolute;
  inset: 0;
  z-index: 250;
  pointer-events: none;
}

.ai2-crop-overlay[hidden],
.ai2-crop-selection[hidden],
.ai2-crop-mask[hidden],
.ai2-crop-error[hidden] {
  display: none !important;
}

/* 只覆盖 contain 之后的真实图片矩形，交互不会落到留白区域。 */
.ai2-crop-image-area {
  position: absolute;
  overflow: visible;
  pointer-events: auto;
  cursor: crosshair;
  touch-action: none;
  outline: none;
}

.ai2-crop-image-area:focus-visible {
  box-shadow: 0 0 0 2px rgba(82, 109, 245, .35);
}

.ai2-crop-mask {
  position: absolute;
  background: rgba(23, 26, 29, .48);
  pointer-events: none;
}

/* 四块遮罩的实际矩形由脚本按归一化选区换算，这里固定遮罩样式与层序。 */
.ai2-crop-mask-top,
.ai2-crop-mask-bottom {
  left: 0;
  right: 0;
  background: rgba(23, 26, 29, .48);
}

.ai2-crop-mask-left,
.ai2-crop-mask-right {
  background: rgba(23, 26, 29, .48);
}

.ai2-crop-mask-top { top: 0; }
.ai2-crop-mask-bottom { bottom: 0; }
.ai2-crop-mask-left { left: 0; }
.ai2-crop-mask-right { right: 0; }

/* 裁剪框主色：跟画布选中态同一个橙，改一处就能整体换色。 */
.ai2-crop-overlay {
  --ai2-crop-accent: #526df5;
}

.ai2-crop-selection {
  position: absolute;
  pointer-events: none;
}

/* 走线虚框：圆角矩形描边，虚线沿弧线走（rx 跟节点图片的 18px 圆角一致）。
   SVG rect 的描边本来就以盒子边线为中心，所以容器必须跟选区完全重合（inset: 0）；
   之前外扩半个线宽反而把整条虚线推出去 0.75px，四角括号就显得"离开虚线"。 */
.ai2-crop-ants {
  position: absolute;
  inset: 0;
  pointer-events: none;
  color: var(--ai2-crop-accent);
}

.ai2-crop-ants svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.ai2-crop-ants rect {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-dasharray: 7 7;
  animation: ai2-crop-ants .6s linear infinite;
}

@keyframes ai2-crop-ants {
  to {
    stroke-dashoffset: -14;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ai2-crop-ants rect {
    animation: none;
  }
}

/* 尺寸胶囊：显示裁剪框在原图上的像素尺寸，配色跟裁剪菜单一致。 */
.ai2-crop-size {
  position: absolute;
  top: 8px;
  right: 26px;
  max-width: calc(100% - 52px);
  padding: 3px 9px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  background: #f7f8fa;
  color: #33383d;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  pointer-events: none;
}

/* 八个控制点：视觉 22×22 括号，命中区 24×24 */
.ai2-crop-handle {
  position: absolute;
  width: 24px;
  height: 24px;
  pointer-events: auto;
  z-index: 2;
  transform: translate(-50%, -50%);
}

/* 角点括号：比虚线粗一倍（3px vs 1.5px），中线整体往选区外挪 3px，跟虚线留出缝隙。
   中线半径 = 虚框圆角 18 + 外挪 3 = 21，盒子外沿半径 22.5 = 21 + 半个线宽，
   盒子边长 48（≥ 2×22.5），偏移 7.5 = 命中区一半 12 - 外挪 3 - 半个线宽 1.5。
   clip 只留靠角 28px：弧切点在角内 18px 处，再往外 5.5px 直臂。 */
.ai2-crop-handle::after {
  content: "";
  position: absolute;
  width: 48px;
  height: 48px;
  border: 3px solid var(--ai2-crop-accent);
  border-radius: 22.5px;
}

.ai2-crop-handle[data-handle="nw"]::after { left: 7.5px; top: 7.5px; clip-path: inset(0 20px 20px 0); }
.ai2-crop-handle[data-handle="ne"]::after { right: 7.5px; top: 7.5px; clip-path: inset(0 0 20px 20px); }
.ai2-crop-handle[data-handle="se"]::after { right: 7.5px; bottom: 7.5px; clip-path: inset(20px 0 0 20px); }
.ai2-crop-handle[data-handle="sw"]::after { left: 7.5px; bottom: 7.5px; clip-path: inset(20px 20px 0 0); }

/* 高亮区的四个圆角：四块矩形遮罩停在选区边线上，选区内侧的角既不在遮罩里、
   又落在圆角虚框之外，会漏出方形亮角。每片补一个 18×18 的「方角 - 四分之一圆」。 */
.ai2-crop-mask-corner {
  position: absolute;
  width: 18px;
  height: 18px;
  background: rgba(23, 26, 29, .48);
  pointer-events: none;
}

.ai2-crop-mask-corner[data-corner="nw"] {
  left: 0;
  top: 0;
  -webkit-mask: radial-gradient(circle at 100% 100%, transparent 18px, #000 18.5px);
  mask: radial-gradient(circle at 100% 100%, transparent 18px, #000 18.5px);
}
.ai2-crop-mask-corner[data-corner="ne"] {
  right: 0;
  top: 0;
  -webkit-mask: radial-gradient(circle at 0% 100%, transparent 18px, #000 18.5px);
  mask: radial-gradient(circle at 0% 100%, transparent 18px, #000 18.5px);
}
.ai2-crop-mask-corner[data-corner="se"] {
  right: 0;
  bottom: 0;
  -webkit-mask: radial-gradient(circle at 0% 0%, transparent 18px, #000 18.5px);
  mask: radial-gradient(circle at 0% 0%, transparent 18px, #000 18.5px);
}
.ai2-crop-mask-corner[data-corner="sw"] {
  left: 0;
  bottom: 0;
  -webkit-mask: radial-gradient(circle at 100% 0%, transparent 18px, #000 18.5px);
  mask: radial-gradient(circle at 100% 0%, transparent 18px, #000 18.5px);
}

/* 边中点只负责拖拽，不再画小方块。 */
.ai2-crop-handle[data-handle="n"]::after,
.ai2-crop-handle[data-handle="e"]::after,
.ai2-crop-handle[data-handle="s"]::after,
.ai2-crop-handle[data-handle="w"]::after {
  display: none;
}

.ai2-crop-handle[data-handle="nw"] { left: 0; top: 0; cursor: nwse-resize; }
.ai2-crop-handle[data-handle="n"] { left: 50%; top: 0; cursor: ns-resize; }
.ai2-crop-handle[data-handle="ne"] { left: 100%; top: 0; cursor: nesw-resize; }
.ai2-crop-handle[data-handle="e"] { left: 100%; top: 50%; cursor: ew-resize; }
.ai2-crop-handle[data-handle="se"] { left: 100%; top: 100%; cursor: nwse-resize; }
.ai2-crop-handle[data-handle="s"] { left: 50%; top: 100%; cursor: ns-resize; }
.ai2-crop-handle[data-handle="sw"] { left: 0; top: 100%; cursor: nesw-resize; }
.ai2-crop-handle[data-handle="w"] { left: 0; top: 50%; cursor: ew-resize; }

/* 取消 / 确定：沿用现有深色主按钮与浅色描边风格 */
.ai2-crop-cancel,
.ai2-crop-confirm {
  position: absolute;
  top: 10px;
  z-index: 5;
  /* 遮罩层是 pointer-events:none，按钮必须显式收回点击，否则真实点击会穿透到图片区域。 */
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 58px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid #171a1d;
  border-radius: var(--ai2-r-field);
  background: #fff;
  color: #171a1d;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.ai2-crop-cancel {
  left: 10px;
}

.ai2-crop-confirm {
  right: 10px;
  background: #171a1d;
  color: #fff;
}

.ai2-crop-cancel:hover,
.ai2-crop-confirm:hover {
  background: #f1f3f5;
  color: #171a1d;
}

.ai2-crop-confirm:hover {
  background: #171a1d;
  color: #fff;
}

.ai2-crop-confirm:disabled,
.ai2-crop-confirm:disabled:hover {
  opacity: .45;
  background: #667078;
  border-color: #667078;
  cursor: not-allowed;
}

.ai2-crop-error {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 6;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 32px);
  padding: 10px 14px;
  border: 1px solid #ccd3d9;
  border-radius: var(--ai2-r-field);
  background: rgba(247, 248, 250, .97);
  color: #3f55c4;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  pointer-events: none;
}

.ai2-crop-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
  border: 0;
  clip: rect(0 0 0 0);
}

/* --------------------------------------------------------------------------
   裁剪工具条：贴着节点下沿的一行胶囊条 —— 关闭 / 比例图标组 / 确定。
   布局照参考稿（分段 + 分隔线 + 右侧主按钮），配色和圆角跟画布走。
   -------------------------------------------------------------------------- */

.ai2-crop-bar {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 32;
  display: flex;
  align-items: center;
  gap: 6px;
  width: max-content;
  max-width: calc(100vw - 16px);
  padding: 6px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  box-shadow: 0 18px 44px rgba(82, 109, 245, .16);
  transform: translateX(-50%);
}

.ai2-crop-bar[hidden] {
  display: none;
}

.ai2-crop-bar-divider {
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: #e3e7ea;
}

/* 关闭：✕ + 工具名，点击即取消裁剪。 */
.ai2-crop-bar .ai2-crop-cancel {
  position: static;
  gap: 5px;
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: none;
  background: transparent;
  color: #667078;
  font-weight: 500;
}

.ai2-crop-bar .ai2-crop-cancel:hover {
  background: #f7f8fa;
  color: #171a1d;
}

/* 比例入口：当前比例图标 + 名称 + 箭头，点开三级菜单。 */
.ai2-crop-ratio-trigger {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #33383d;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}

.ai2-crop-ratio-trigger:hover {
  background: #f7f8fa;
}

/* 条本身是白的，所以展开态用米白底 + 描边区分。 */
.ai2-crop-ratio-trigger[aria-expanded="true"] {
  border-color: #e3e7ea;
  background: #f7f8fa;
  color: #171a1d;
}

.ai2-crop-ratio-trigger .ai2-crop-ratio-icon {
  display: grid;
  place-items: center;
  color: #9aa2a9;
}

.ai2-crop-ratio-trigger[aria-expanded="true"] .ai2-crop-ratio-icon {
  color: #526df5;
}

.ai2-crop-ratio-trigger > svg {
  color: #9aa2a9;
}

/* 确定：沿用画布的深色主按钮。 */
.ai2-crop-bar .ai2-crop-confirm {
  position: static;
  flex: 0 0 auto;
  min-width: 60px;
  height: 32px;
  padding: 0 14px;
}

/* 三级比例菜单：3 列 2 行，水平居中对齐二级菜单（JS 会写 left 做视口内收）。 */
.ai2-crop-ratio-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, 92px);
  gap: 6px;
  padding: 8px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-panel);
  background: #fff;
  box-shadow: 0 14px 32px rgba(82, 109, 245, .12);
  pointer-events: auto;
  transform: translateX(-50%);
}

.ai2-crop-ratio-panel[hidden] {
  display: none;
}

/* 二级菜单贴在节点上方时，三级菜单朝上展开。 */
.ai2-crop-ratio-panel-up {
  top: auto;
  bottom: calc(100% + 8px);
}

/* 三级菜单里的选项：图标在左、文字在右；外层框是白色，所以选项用米白底区分层级。 */
.ai2-crop-ratio {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  height: 38px;
  padding: 0 8px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field);
  background: #f7f8fa;
  color: #667078;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}

.ai2-crop-ratio .ai2-crop-ratio-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
}

.ai2-crop-ratio:hover {
  border-color: #ccd3d9;
  color: #171a1d;
}

.ai2-crop-ratio:focus-visible {
  outline: 2px solid #526df5;
  outline-offset: 1px;
}

.ai2-crop-ratio.active {
  border-color: #171a1d;
  background: #171a1d;
  color: #fff;
}

@media (max-width: 900px) {
  .ai2-crop-bar {
    border-radius: var(--ai2-r-panel);
  }

  .ai2-crop-ratio-panel {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    width: min(304px, calc(100vw - 24px));
  }
}

/* ==========================================================================
   多选：只保留应用自己的圆角虚线框，去掉 ReactFlow 自带的蓝色长方形
   ========================================================================== */

/* 选中多个节点后 ReactFlow 会画一个蓝色矩形，这里是重复的，直接去掉。 */
.react-flow__nodesselection-rect {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

/* 画布背景去掉点阵，只留 .canvas-area 的暖色渐变。 */
.react-flow__background {
  display: none !important;
}

/* 拖拽框选时的预览框也改成暖棕主色，画布上不再出现蓝色长方形。 */
.react-flow__selection {
  background: rgba(102, 112, 120, .08) !important;
  border: 1px dashed rgba(154, 162, 169, .95) !important;
}

/* 多选圆角矩形：底和虚线垫在节点下面（z-index 低于节点渲染层），不遮挡节点。
   打组后这条虚线同时充当分组的常驻外框——分组节点自身不画任何边框。 */
.multi-sel-fill {
  position: fixed;
  z-index: 1;
  pointer-events: none;
  border: 2px dashed rgba(154, 162, 169, .9);
  border-radius: var(--ai2-r-panel);
  background: rgba(102, 112, 120, .05);
}

/* 外框容器只负责定位拉出把手，并把它抬到节点之上，保证可点可拖。 */
.multi-sel-box {
  z-index: 10;
  border: none;
  background: none;
}

/* 拉出到下游的把手：比原来大一圈，方便抓取。 */
.multi-sel-plus {
  right: -21px;
  width: 42px;
  height: 42px;
  z-index: 10;
}

/* ==========================================================================
   节点运行中的动效（Aurora 渐变 + 细密点阵呼吸）
   全部规则集中在 ai2-motion-patch.css 第 13 节，这里不再重复声明。
   ========================================================================== */

/* ==========================================================================
   选中节点时，它的上游连线流动起来（不选中节点则保持原样）
   ========================================================================== */

/* #root 前缀是必须的：ai2-restyle.css 的 `#root .react-flow__edge-path` 会盖掉
   不带 #root 的同色声明，流动虚线就会显示成灰色。 */
#root .react-flow__edge-path.custom-edge-path.ai2-edge-flow {
  stroke: #526df5; /* 与节点选中描边同色 */
  stroke-dasharray: 11 8;
  animation: ai2-edge-flow 0.75s linear infinite;
}

/* 虚线段朝下游（source -> target）推进 */
@keyframes ai2-edge-flow {
  to {
    stroke-dashoffset: -19;
  }
}

@media (prefers-reduced-motion: reduce) {
  #root .react-flow__edge-path.custom-edge-path.ai2-edge-flow {
    animation: none;
  }
}

/* ==========================================================================
   按需求隐藏的运行入口（按钮仍在 DOM 里，只是不显示）
   顶部「全部运行」/ 运行日志「上传图片」「运行队列」/ 分组「整组执行」
   ========================================================================== */

.ai2-control-hidden {
  display: none !important;
}

/* ==========================================================================
   顶部工具栏只保留「API 设置」
   适配视图/对齐/分布/自动排版/打组/解组 由选框浮层接管，按钮仍留在 DOM 里
   （浮层靠程序化点击这些按钮复用原有逻辑，不能删节点）。
   ========================================================================== */

.top-toolbar button:not(.settings-button) {
  display: none !important;
}

/* 分组不再画外框和「分组节点」标题：只保留它作为容器的行为（整体拖动、组内连线、解组）。 */
.group-node,
.group-node.selected {
  border: none !important;
  background: none !important;
  box-shadow: none !important;
}

.group-title {
  display: none !important;
}

/* ==========================================================================
   框选浮层：选中多个节点（或分组）时浮现在选框外侧的操作条
   ========================================================================== */

.ai2-sel-toolbar {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 5px;
  border-radius: var(--ai2-r-panel);
  background: #ffffffeb;
  border: 1px solid rgba(23, 26, 29, .08);
  box-shadow: 0 14px 34px rgba(82, 109, 245, .14);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  transform: translate(-50%, -100%);
  animation: ai2-sel-toolbar-in 0.14s ease-out;
}

/* 选框顶到屏幕上沿时翻到下方 */
.ai2-sel-toolbar.ai2-sel-toolbar-below {
  transform: translate(-50%, 0);
}

.ai2-sel-toolbar.ai2-sel-toolbar-hidden {
  display: none;
}

.ai2-sel-toolbar button {
  height: 30px;
  padding: 0 9px;
  border-radius: var(--ai2-r-field);
  background: transparent;
  color: #667078;
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  white-space: nowrap;
}

.ai2-sel-toolbar button:hover {
  background: #f7f8fa;
  color: #171a1d;
}

.ai2-sel-toolbar button:active {
  background: #e3e7ea;
}

.ai2-sel-toolbar button svg {
  display: block;
}

.ai2-sel-toolbar-sep {
  width: 1px;
  height: 20px;
  margin: 0 3px;
  background: #e3e7ea;
}

@keyframes ai2-sel-toolbar-in {
  from {
    opacity: 0;
    transform: translate(-50%, -100%) scale(0.94);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ai2-sel-toolbar {
    animation: none;
  }
}


/* ==========================================================================
   节点二级下拉菜单（清晰度 / 比例）照参考图重排
   必须带 #root 前缀并加 !important：既有的 `.compact-toolbar .compact-pill > .option-popover`
   和 `#root :where(button, .option-popover)` 已经用 !important 锁死了底色与圆角。
   ========================================================================== */

#root .compact-size-popover {
  padding: 16px !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-panel) !important;
  background: #f7f8fa !important;
  box-shadow: 0 22px 54px rgba(82, 109, 245, .16) !important;
}

#root .compact-popover-title {
  margin: 14px 0 8px !important;
  color: #9aa2a9 !important;
  font-weight: 600 !important;
}

#root .compact-popover-title:first-child {
  margin-top: 0 !important;
}

/* 清晰度 / 张数：一条分段控件，选中项浮起白底 */
#root .option-popover-quality,
#root .option-popover-count {
  gap: 4px !important;
  padding: 4px !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-field) !important;
  background: #f1f3f5 !important;
}

#root .option-popover-quality button,
#root .option-popover-count button {
  height: 32px !important;
  min-height: 0 !important;
  padding: 0 8px !important;
  border: 1px solid transparent !important;
  border-radius: var(--ai2-r-field) !important;
  background: transparent !important;
  color: #667078 !important;
  font-size: 12px !important;
  font-weight: 600 !important;
}

#root .option-popover-quality button:hover,
#root .option-popover-count button:hover {
  color: #171a1d !important;
}

#root .option-popover-quality button.active,
#root .option-popover-count button.active {
  border-color: #e3e7ea !important;
  background: #fff !important;
  color: #33383d !important;
  box-shadow: 0 2px 8px rgba(82, 109, 245, .1) !important;
}

/* 比例：四列网格，形状图标在上、文字在下 */
#root .option-popover-ratio {
  gap: 8px !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
}

#root .option-popover-ratio button {
  height: 64px !important;
  min-height: 0 !important;
  padding: 0 4px !important;
  border: 1px solid #e3e7ea !important;
  border-radius: var(--ai2-r-field) !important;
  background: #fff !important;
  color: #667078 !important;
}

#root .option-popover-ratio button:hover {
  border-color: #ccd3d9 !important;
  color: #171a1d !important;
}

#root .option-popover-ratio button.active {
  border-color: #8e9bf9 !important;
  background: #eef1ff !important;
  color: #3f55c4 !important;
}

#root .option-popover-ratio .ratio-option-inner {
  flex-direction: column;
  gap: 6px;
}

/* 形状图标放大到一眼能看出比例 */
#root .option-popover-ratio .ratio-1-1 { width: 20px; height: 20px; }
#root .option-popover-ratio .ratio-4-3 { width: 24px; height: 18px; }
#root .option-popover-ratio .ratio-3-4 { width: 18px; height: 24px; }
#root .option-popover-ratio .ratio-3-2 { width: 26px; height: 18px; }
#root .option-popover-ratio .ratio-2-3 { width: 18px; height: 26px; }
#root .option-popover-ratio .ratio-16-9 { width: 28px; height: 16px; }
#root .option-popover-ratio .ratio-9-16 { width: 16px; height: 28px; }
#root .option-popover-ratio .ratio-auto {
  width: 22px;
  height: 22px;
  border: 1.5px dashed currentColor;
  border-radius: var(--ai2-r-tag);
  font-size: 12px;
  line-height: 20px;
}

/* ==========================================================================
   张数 −/+ 步进器（ai2-node-count-stepper.js）
   原「N张」胶囊只是被藏起来：步进器要靠它内部的真实选项来限幅。
   ========================================================================== */

/* 隐藏必须写在样式表里、按 title 命中，不能由 JS 给胶囊加类。
   React 只在 className prop 变化时回写属性，而步进恰好让它在 `compact-pill` 和
   `compact-pill active` 之间来回切，JS 加的隐藏类会被连根抹掉 —— 实测每步闪出
   1~2 帧原胶囊。样式表规则 React 动不了，连它新建的胶囊也第一帧就不可见。
   下拉挂在胶囊内部，跟着一起不可见，所以步进时静默展开也不会露出来。 */
#root .compact-toolbar > .compact-pill[title="生成张数"] {
  display: none !important;
}

#root .ai2-count-stepper {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  /* 工具栏是 flex 且不换行，原本由 .compact-run 的 margin-left:auto 把右侧撑开；
     步进器插到它前面后改由这里撑，两者一起贴到行尾，张数就落在运行按钮旁边。 */
  margin-left: auto;
  height: 46px;
  padding: 0 5px;
  border: 1px solid #e3e7ea;
  border-radius: var(--ai2-r-field) !important;
  background: #f1f3f5;
}

#root .ai2-count-stepper button {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 50% !important;
  background: transparent;
  color: #667078;
  font-size: 16px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
}

#root .ai2-count-stepper button:hover {
  background: #fff;
  color: #171a1d;
}

#root .ai2-count-stepper span {
  min-width: 20px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  color: #33383d;
}

/* 张数和运行并成同一个胶囊：先抵消工具栏 12px 的 gap，再把圆点压进胶囊右端 18px，
   胶囊用上面的 padding-right 给圆点留出空位。圆点是后一个兄弟，天然盖在胶囊之上。 */
#root .ai2-count-stepper + .compact-run {
  margin-left: -30px;
}

/* ==========================================================================
   节点文本输入框：去掉圆角矩形外框（边框 / 圆角 / 底色 / 聚焦光环）
   只去框：宽高、内边距、字号、行高、resize、光标与选区行为一律照旧。
   必须带 #root 前缀并加 !important —— `#root :where(... textarea ...)` 已把圆角
   锁成 var(--ai2-radius) 24px，:where() 自身特异性为 0，但 #root 的 id 仍高于
   `.compact-panel .compact-textarea` 这类 0,2,0 的选择器。
   ========================================================================== */

#root .compact-textarea,
#root .node-textarea,
#root .gen-expand-textarea {
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

/* ==========================================================================
   gpt-image 的「生成质量」三级菜单：还原成与模型 / 尺寸菜单同款的圆角卡片
   上面 `#root .option-popover-quality` 那组是给尺寸面板里的「清晰度」分段控件写的，
   但它同时命中了直接挂在胶囊下的独立弹层 —— 1,1,0 + !important 压过卡片规则的 0,3,0，
   于是质量菜单变成灰色 999px 轨道 + 32px 透明按钮。这里用更高特异性还原卡片。
   描边、阴影、选中项描边一律走 --ai2-* 令牌，和模型 / 尺寸菜单实测值一致
   （原先手抄的 0 18px 42px rgba(82,109,245,.18) 蓝阴影 + #526df5 描边是这两个菜单独有的）。
   ========================================================================== */

#root .compact-toolbar .compact-pill > .option-popover-quality {
  gap: 6px !important;
  padding: 8px !important;
  border: 1px solid var(--ai2-border) !important;
  border-radius: var(--ai2-r-field) !important;
  background: #fff !important;
  box-shadow: var(--ai2-shadow-float) !important;
}

#root .compact-toolbar .compact-pill > .option-popover-quality button {
  height: 44px !important;
  min-height: 44px !important;
  padding: 0 16px !important;
  border: 1px solid transparent !important;
  border-radius: var(--ai2-r-panel) !important;
  background: #f7f8fa !important;
  color: #667078 !important;
  font-size: 13px !important;
  justify-content: center !important;
  text-align: center !important;
}

#root .compact-toolbar .compact-pill > .option-popover-quality button:hover,
#root .compact-toolbar .compact-pill > .option-popover-quality button.active {
  /* 描边和阴影都对齐其他菜单的选中项：淡紫描边、不加任何内阴影。
     底色取 #eef1ff 而不是卡片规则里写的 #fff：后面「全局暖桃色状态」那条
     同为 0,4,1 + !important，靠源序压过了它，其他菜单选中项实测就是 #eef1ff。 */
  background: #eef1ff !important;
  border-color: var(--ai2-accent-line) !important;
  color: #3f55c4 !important;
  box-shadow: none !important;
}

/* ==========================================================================
   宫格切图：二级菜单里的「宫格切图」→ 向下的三级菜单选规格 → 节点上方换成四级操作条，
   图片上盖一层可多选的宫格，选好点「创建图片节点」把选中的格子切出来。
   ========================================================================== */

/* 二级菜单里的入口（图标 + 文字，和其它项同一套排法）。 */
#root .image-node.compact-node > .compact-top > .compact-split-btn::after { content: "宫格切图"; }

#root .image-node.compact-node > .compact-top > .compact-split-btn.active {
  background: var(--ai2-accent-soft, #eef1ff) !important;
  color: var(--ai2-accent-text, #3f55c4) !important;
}

/* 三级菜单打开时，把整条二级菜单抬到节点标题（z-index 240）之上，
   否则菜单顶部会被标题文字压住。 */
#root .image-node.compact-node > .compact-top:has(.ai2-split-menu) {
  z-index: 300 !important;
}

/* 三级菜单：跟着二级菜单往下弹（二级菜单本身浮在节点上方）。 */
.ai2-split-menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 130;
  width: 210px;
  padding: 8px;
  border: 1px solid var(--ai2-border, #e3e7ea);
  border-radius: var(--ai2-r-panel, 14px);
  background: var(--ai2-surface, #fff);
  box-shadow: var(--ai2-shadow-float, 0 18px 42px rgba(24, 32, 38, .16));
}

.ai2-split-menu-title {
  padding: 6px 10px 8px;
  color: var(--ai2-text-3, #9aa2a9);
  font-size: 12px;
  font-weight: 600;
}

.ai2-split-option {
  width: 100%;
  height: 34px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  border: 0;
  border-radius: var(--ai2-r-field, 10px);
  background: transparent;
  color: var(--ai2-text, #171a1d);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.ai2-split-option:hover,
.ai2-split-option:focus-visible {
  background: var(--ai2-hover, #f1f3f5);
  outline: none;
}

.ai2-split-custom {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 8px 10px 4px;
  border-top: 1px solid var(--ai2-line, #edeff2);
  color: var(--ai2-text-2, #667078);
  font-size: 12px;
}

.ai2-split-custom-label { flex: 1 1 auto; font-weight: 600; }

.ai2-split-custom input {
  width: 46px;
  height: 30px;
  padding: 0 6px;
  border: 1px solid var(--ai2-border-strong, #ccd3d9);
  border-radius: var(--ai2-r-field, 10px);
  background: var(--ai2-surface, #fff);
  color: var(--ai2-text, #171a1d);
  font-size: 12px;
  text-align: center;
}

.ai2-split-custom-go {
  height: 30px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--ai2-r-field, 10px);
  background: var(--ai2-accent-soft, #eef1ff);
  color: var(--ai2-accent-text, #3f55c4);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

/* 四级操作条：和二级菜单同一个位置、同一条胶囊。 */
.ai2-split-bar {
  gap: 6px;
  padding: 6px 10px;
}

/* 裁剪 / 画笔的补丁是按 .compact-top 注入按钮的，切图条同样带这个类，
   所以它们会被塞进操作条里 —— 切图模式下先把它们藏掉。 */
.ai2-split-bar > .ai2-crop-trigger,
.ai2-split-bar > .ai2-paint-trigger {
  display: none !important;
}

.ai2-split-bar .ai2-split-icon-btn {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ai2-text-2, #667078);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.ai2-split-bar .ai2-split-icon-btn:hover,
.ai2-split-bar .ai2-split-icon-btn:focus-visible,
.ai2-split-bar .ai2-split-icon-btn.is-on {
  background: var(--ai2-hover, #f1f3f5);
  color: var(--ai2-text, #171a1d);
  outline: none;
}

.ai2-split-bar .ai2-split-size {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 8px;
  border-radius: var(--ai2-r-field, 10px);
  background: var(--ai2-surface-2, #f7f8fa);
  color: var(--ai2-text-2, #667078);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.ai2-split-bar .ai2-split-count {
  padding: 0 2px;
  color: var(--ai2-text-3, #9aa2a9);
  font-size: 12px;
  white-space: nowrap;
}

.ai2-split-bar .ai2-split-create {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--ai2-r-field, 10px);
  background: transparent;
  color: var(--ai2-text-2, #667078);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.ai2-split-bar .ai2-split-create:hover:not(:disabled),
.ai2-split-bar .ai2-split-create:focus-visible {
  background: var(--ai2-accent-soft, #eef1ff);
  color: var(--ai2-accent-text, #3f55c4);
  outline: none;
}

.ai2-split-bar .ai2-split-create:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}

/* 图上的宫格：和媒体区同位置同比例，格子可多选。 */
.ai2-split-grid {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 70;
  display: grid;
  grid-template-columns: repeat(var(--ai2-split-cols, 2), minmax(0, 1fr));
  grid-template-rows: repeat(var(--ai2-split-rows, 2), minmax(0, 1fr));
  /* 直角：框选出来的矩形就是要切出来的矩形，
     所以这里不能继承媒体区的圆角，也不能裁掉格子外框。 */
  border-radius: 0;
  overflow: visible;
}

/* 选择格是 button，restyle 里 `#root :where(button…)` 会把圆角钉成 24px，
   所以这里要用 #root 前缀 + !important 才压得住。 */
#root .ai2-split-grid .ai2-split-cell {
  border-radius: 0 !important;
}

.ai2-split-cell {
  position: relative;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .55);
  background: transparent;
  cursor: pointer;
  transition: background 0.12s ease, box-shadow 0.12s ease;
}

.ai2-split-cell:hover,
.ai2-split-cell:focus-visible {
  background: rgba(82, 109, 245, .14);
  outline: none;
}

.ai2-split-cell.is-on {
  background: rgba(82, 109, 245, .1);
  box-shadow: inset 0 0 0 2px var(--ai2-accent, #526df5);
}

/* 选中格的「行-列」角标（参考图里那个小白标签）。 */
.ai2-split-cell-tag {
  position: absolute;
  left: 50%;
  top: 6px;
  transform: translateX(-50%);
  padding: 2px 6px;
  border-radius: var(--ai2-r-tag, 8px);
  background: rgba(255, 255, 255, .92);
  color: var(--ai2-text, #171a1d);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .ai2-split-cell { transition: none; }
}
