/* static/css/flow-canvas.css — extracted from index.html (FrameFlow prototype) */
  /* Project overview: infinite workflow canvas */
  .project-flow-canvas {
    margin-top: 16px; padding: 0; position: relative; overflow: hidden;
    background-color: var(--bg);
    background-image:
      radial-gradient(rgba(255,255,255,0.07) 1px, transparent 1px),
      radial-gradient(rgba(74,222,128,0.04) 1px, transparent 1px);
    background-size: 22px 22px, 44px 44px;
    background-position: 0 0, 11px 11px;
    border: 1px solid var(--border); border-radius: var(--radius);
  }
  .flow-canvas-viewport {
    position: relative; width: 100%; height: 520px; overflow: hidden;
    border-radius: var(--radius); cursor: grab;
    background: transparent;
    touch-action: none;
  }
  .flow-canvas-viewport:active { cursor: grabbing; }
  .flow-canvas-viewport.panning .flow-node { pointer-events: none; }
  .flow-canvas-layer { position: absolute; inset: 0; width: 4000px; height: 4000px; transform-origin: 0 0; will-change: transform; background: transparent; }
  .flow-canvas-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; }
  .flow-canvas-svg path { fill: none; stroke: rgba(74,222,128,0.22); stroke-width: 2; }
  .flow-canvas-svg path.done { stroke: rgba(59,130,246,0.55); }
  .flow-nodes-layer { position: absolute; inset: 0; z-index: 2; }
  .flow-node.type-center {
    width: 300px; height: auto; min-height: 0; padding: 0;
    display: flex; flex-direction: column;
    background: rgba(22,24,30,0.52);
    backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
    border: 1px solid rgba(255,255,255,0.16);
    box-shadow: 0 20px 55px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.14), inset 0 -1px 0 rgba(0,0,0,0.25), 0 0 0 1px rgba(74,222,128,0.10);
    z-index: 3; border-radius: 24px; overflow: hidden; cursor: grab;
    transition: box-shadow .25s ease, border-color .25s ease, transform .2s ease;
  }
  /* 悬停发光：弱亮度、大光晕 */
  .flow-node.type-center:hover {
    border-color: rgba(74,222,128,0.5);
    box-shadow: 0 0 24px rgba(74,222,128,0.28), 0 0 62px rgba(74,222,128,0.12), 0 20px 55px rgba(0,0,0,0.45), inset 0 1px 0 rgba(255,255,255,0.16);
  }
  .flow-node.type-center.dragging { cursor: grabbing; box-shadow: 0 0 26px rgba(74,222,128,0.34), 0 0 68px rgba(74,222,128,0.15), inset 0 1px 0 rgba(255,255,255,0.16); }
  .flow-node.type-center::before { background: radial-gradient(140% 90% at 50% 0%, rgba(74,222,128,0.2), transparent 60%); opacity: .8; }
  /* 顶部图片区：按缩略图实际比例自适应（无图默认 16:9） */
  .flow-node.type-center .fcenter-thumb { width: 100%; aspect-ratio: 16 / 9; height: auto; flex: 0 0 auto; position: relative; display: grid; place-items: center; overflow: hidden; background: linear-gradient(135deg, rgba(74,222,128,.22), rgba(34,211,238,.14)); }
  .flow-node.type-center .fcenter-thumb::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 55%; background: linear-gradient(to top, rgba(10,12,16,0.42) 0%, rgba(10,12,16,0.2) 45%, transparent 100%); pointer-events: none; }
  .flow-node.type-center .fcenter-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .flow-node.type-center .fcenter-thumb-ph { color: rgba(255,255,255,0.5); }
  /* 中间信息区：约 30%，磨砂毛玻璃 */
  .flow-node.type-center .fcenter-body {
    position: static; z-index: 3; display: flex; flex-direction: column; justify-content: center;
    text-align: left; padding: 12px 16px 14px;
    background: linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.03));
    backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%);
    border-top: 1px solid rgba(255,255,255,0.05); pointer-events: none;
  }
  /* 项目类型标签 */
  .flow-node.type-center .fcenter-tag {
    display: inline-block; align-self: flex-start; font-size: 10.5px; font-weight: 700; color: #052e16;
    background: linear-gradient(135deg, #4ade80, #22d3ee); border-radius: 999px; padding: 2px 10px; margin-bottom: 6px; letter-spacing: .02em;
  }
  .flow-node.type-center .fcenter-body strong { display: block; font-size: 15.5px; font-weight: 800; color: #fff; max-width: 268px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 3px rgba(0,0,0,0.35); }
  /* 项目概述：最多 3 行 */
  .flow-node.type-center .fcenter-desc {
    margin-top: 6px; font-size: 11.5px; line-height: 1.5; color: rgba(255,255,255,0.78);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  }
  .flow-node.type-center .fcenter-info { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 5px; margin-top: 9px; }
  .flow-node.type-center .fcenter-info span { font-size: 10.5px; color: rgba(255,255,255,0.92); background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.18); border-radius: 999px; padding: 3px 9px; white-space: nowrap; backdrop-filter: blur(4px); }
  /* 进度：节点右上角徽标 */
  /* 根节点（项目立项）状态徽标：已完成 */
  .flow-node.type-center .fcenter-status {
    position: absolute; top: 12px; left: 12px; right: auto; z-index: 4;
    font-size: 11px; font-weight: 800; letter-spacing: .03em;
    color: #052e16; background: linear-gradient(135deg, #4ade80, #22d3ee);
    border-radius: 999px; padding: 3px 10px;
    box-shadow: 0 2px 10px rgba(74,222,128,0.35);
  }
  .flow-node.type-center .fcenter-prog {
    position: absolute; top: 10px; right: 10px; z-index: 6;
    font-size: 11px; font-weight: 800; color: #fff; letter-spacing: .02em;
    background: rgba(8,10,14,0.55); border: 1px solid rgba(255,255,255,0.28); border-radius: 999px; padding: 3px 10px;
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  }
  .flow-node.type-center .fhandle { cursor: grab; }
  html[data-theme="light"] .flow-node.type-center { background: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.7); }
  html[data-theme="light"] .flow-node.type-center:hover { box-shadow: 0 0 22px rgba(34,197,94,0.24), 0 0 54px rgba(34,197,94,0.1), 0 18px 40px rgba(0,0,0,0.12); border-color: rgba(22,163,74,0.42); }
  html[data-theme="light"] .flow-node.type-center .fcenter-body { background: linear-gradient(180deg, rgba(255,255,255,0.85), rgba(255,255,255,0.65)); border-top-color: rgba(0,0,0,0.06); }
  html[data-theme="light"] .flow-node.type-center .fcenter-body strong { color: #111827; text-shadow: none; }
  html[data-theme="light"] .flow-node.type-center .fcenter-desc { color: #4b5563; }
  html[data-theme="light"] .flow-node.type-center .fcenter-tag { color: #fff; }
  html[data-theme="light"] .flow-node.type-center .fcenter-prog { color: #111827; background: rgba(255,255,255,0.85); border-color: rgba(0,0,0,0.15); }
  html[data-theme="light"] .flow-node.type-center .fcenter-info span { color: #374151; background: rgba(255,255,255,0.7); border-color: rgba(0,0,0,0.12); }

  /* Connection ports */
  .fport {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--bg); border: 2px solid var(--neon);
    cursor: crosshair; z-index: 20;
    opacity: 0; transition: opacity .2s ease, transform .15s ease, box-shadow .2s ease;
    box-shadow: 0 0 0 0 rgba(74,222,128,0.0);
  }
  .flow-node:hover .fport { opacity: 1; }
  .fport:hover { transform: translateY(-50%) scale(1.25); box-shadow: 0 0 12px rgba(74,222,128,0.45); }
  .fport-left { left: -6px; }
  .fport-right { right: -6px; }
  .fport-top { top: -6px; left: 50%; transform: translateX(-50%); }
  .fport-bottom { top: auto; bottom: -6px; left: 50%; transform: translateX(-50%); }
  .fport-top:hover, .fport-bottom:hover { transform: translateX(-50%) scale(1.25); }
  .fport::after {
    content: ''; position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 28px; height: 28px; border-radius: 50%;
    background: transparent;
  }
  .flow-node.dragging .fport { opacity: 0; }
  .flow-canvas-svg path.temp { stroke: var(--neon); stroke-width: 2; stroke-dasharray: 5 5; opacity: .85; marker-end: url(#flowArrow); }

  .fport-label {
    position: absolute;
    top: 50%; transform: translateY(-50%);
    font-size: 9px; font-weight: 800; color: var(--text-muted);
    white-space: nowrap; opacity: 0; transition: opacity .2s ease;
    pointer-events: none;
  }
  .fport-left .fport-label { right: 16px; }
  .fport-right .fport-label { left: 16px; }
  .flow-node:hover .fport-label { opacity: 1; }

  /* Node hierarchy roles */
  .flow-node.role-pre-task { border-color: rgba(59,130,246,0.22); }
  .flow-node.role-pre-task:hover { border-color: rgba(59,130,246,0.48); }
  .flow-node.role-pre-task::before { background: radial-gradient(120% 80% at 20% 0%, rgba(59,130,246,0.12), transparent 60%); }
  .flow-node.role-pre-task .ficon { background: linear-gradient(145deg, rgba(59,130,246,0.18), rgba(59,130,246,0.05)); color: #60a5fa; }

  .flow-node.role-post-task { border-color: rgba(74,222,128,0.18); }
  .flow-node.role-post-task:hover { border-color: rgba(74,222,128,0.45); }
  .flow-node.role-post-task::before { background: radial-gradient(120% 80% at 20% 0%, rgba(74,222,128,0.13), transparent 60%); }
  .flow-node.role-post-task .ficon { background: linear-gradient(145deg, rgba(74,222,128,0.18), rgba(74,222,128,0.05)); color: var(--neon-bright); }

  .flow-node.role-sub-task { width: 200px; min-height: 96px; border-color: rgba(168,85,247,0.20); }
  .flow-node.role-sub-task:hover { border-color: rgba(168,85,247,0.45); }
  .flow-node.role-sub-task::before { background: radial-gradient(120% 80% at 20% 0%, rgba(168,85,247,0.11), transparent 60%); }
  .flow-node.role-sub-task .ficon { background: linear-gradient(145deg, rgba(168,85,247,0.16), rgba(168,85,247,0.04)); color: #c084fc; }

  /* Resource nodes */
  .flow-node.role-resource { width: 160px; min-height: 78px; padding: 11px 13px; gap: 8px; border-radius: 16px; }
  .flow-node.role-resource::before { border-radius: 16px 16px 0 0; height: 55%; }
  .flow-node.role-resource .fhead { gap: 8px; }
  .flow-node.role-resource .ficon { width: 30px; height: 30px; border-radius: 9px; }
  .flow-node.role-resource .ficon svg { width: 16px; height: 16px; }
  .flow-node.role-resource .ftitle { font-size: 13px; }
  .flow-node.role-resource .fsubtitle { font-size: 10px; }
  .flow-node.role-resource .fbody { padding-top: 7px; }

  .flow-node.role-resource.type-text { border-color: rgba(168,85,247,0.20); }
  .flow-node.role-resource.type-text::before { background: radial-gradient(120% 80% at 20% 0%, rgba(168,85,247,0.10), transparent 60%); }
  .flow-node.role-resource.type-text .ficon { background: linear-gradient(145deg, rgba(168,85,247,0.16), rgba(168,85,247,0.04)); color: #c084fc; }

  .flow-node.role-resource.type-image { border-color: rgba(59,130,246,0.20); }
  .flow-node.role-resource.type-image::before { background: radial-gradient(120% 80% at 20% 0%, rgba(59,130,246,0.10), transparent 60%); }
  .flow-node.role-resource.type-image .ficon { background: linear-gradient(145deg, rgba(59,130,246,0.16), rgba(59,130,246,0.04)); color: #93c5fd; }

  .flow-node.role-resource.type-video { border-color: rgba(236,72,153,0.20); }
  .flow-node.role-resource.type-video::before { background: radial-gradient(120% 80% at 20% 0%, rgba(236,72,153,0.10), transparent 60%); }
  .flow-node.role-resource.type-video .ficon { background: linear-gradient(145deg, rgba(236,72,153,0.16), rgba(236,72,153,0.04)); color: #f472b6; }

  .flow-node.role-resource.type-audio { border-color: rgba(245,158,11,0.20); }
  .flow-node.role-resource.type-audio::before { background: radial-gradient(120% 80% at 20% 0%, rgba(245,158,11,0.10), transparent 60%); }
  .flow-node.role-resource.type-audio .ficon { background: linear-gradient(145deg, rgba(245,158,11,0.16), rgba(245,158,11,0.04)); color: #fbbf24; }

  .flow-node.role-resource.type-script { border-color: rgba(14,165,233,0.20); }
  .flow-node.role-resource.type-script::before { background: radial-gradient(120% 80% at 20% 0%, rgba(14,165,233,0.10), transparent 60%); }
  .flow-node.role-resource.type-script .ficon { background: linear-gradient(145deg, rgba(14,165,233,0.16), rgba(14,165,233,0.04)); color: #38bdf8; }

  .flow-node.role-resource.type-storyboard { border-color: rgba(99,102,241,0.20); }
  .flow-node.role-resource.type-storyboard::before { background: radial-gradient(120% 80% at 20% 0%, rgba(99,102,241,0.10), transparent 60%); }
  .flow-node.role-resource.type-storyboard .ficon { background: linear-gradient(145deg, rgba(99,102,241,0.16), rgba(99,102,241,0.04)); color: #a5b4fc; }

  .flow-node {
    position: absolute; width: 240px; min-height: 116px; padding: 16px;
    border-radius: 22px; background: rgba(20,22,28,0.72);
    border: 1px solid rgba(255,255,255,0.09); cursor: pointer;
    transition: box-shadow .28s ease, border-color .25s ease, transform .18s ease;
    user-select: none; box-shadow: 0 16px 40px rgba(0,0,0,0.48), inset 0 1px 0 rgba(255,255,255,0.04);
    display: flex; flex-direction: column; gap: 12px;
    touch-action: none;
  }
  .flow-node::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 60%;
    border-radius: 22px 22px 0 0;
    background: radial-gradient(120% 80% at 20% 0%, rgba(74,222,128,0.14), transparent 60%);
    pointer-events: none; opacity: .65; transition: opacity .25s ease;
  }
  .flow-node:hover { transform: translateY(-3px) scale(1.005); border-color: rgba(74,222,128,0.42); box-shadow: 0 24px 58px rgba(0,0,0,0.55), 0 0 0 1px rgba(74,222,128,0.12), inset 0 1px 0 rgba(255,255,255,0.06); }
  .flow-node:hover::before { opacity: .9; }
  .flow-node.active { border-color: rgba(74,222,128,0.55); background: linear-gradient(160deg, rgba(74,222,128,0.10), rgba(20,22,28,0.78)); box-shadow: 0 0 0 1px rgba(74,222,128,0.28), 0 20px 56px rgba(0,0,0,0.52), 0 0 40px rgba(74,222,128,0.10); }
  .flow-node.done { border-color: rgba(59,130,246,0.38); }
  .flow-node.done::before { background: radial-gradient(120% 80% at 20% 0%, rgba(59,130,246,0.16), transparent 60%); }
  .flow-node.pending { opacity: .78; }
  .flow-node.dragging { opacity: .92; z-index: 50; transform: scale(1.03); }
  .flow-node.selected { border-color: rgba(74,222,128,0.85) !important; box-shadow: 0 0 0 2px rgba(74,222,128,0.85), 0 24px 60px rgba(0,0,0,0.6), 0 0 48px rgba(74,222,128,0.14); }
  .flow-select-rect { position: absolute; border: 1px solid rgba(74,222,128,0.9); background: rgba(74,222,128,0.12); border-radius: 4px; pointer-events: none; z-index: 40; display: none; }

  .flow-node .fhandle { position: absolute; inset: 0; border-radius: 22px; z-index: 1; }
  .flow-node .fglow { position: absolute; inset: 0; border-radius: 22px; pointer-events: none; z-index: 0; opacity: .55; transition: opacity .25s ease; }
  .flow-node:hover .fglow { opacity: .85; }

  .flow-node .fhead { position: relative; z-index: 2; display: flex; align-items: flex-start; gap: 12px; }
  .flow-node .ficon {
    width: 40px; height: 40px; border-radius: 12px; flex-shrink: 0;
    display: grid; place-items: center;
    background: linear-gradient(145deg, rgba(255,255,255,0.10), rgba(255,255,255,0.04));
    border: 1px solid rgba(255,255,255,0.08);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 6px 14px rgba(0,0,0,0.25);
    color: var(--text-dim);
  }
  .flow-node .ficon svg { width: 20px; height: 20px; }
  .flow-node .ftitles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; padding-top: 1px; }
  .flow-node .ftitle { font-size: 15px; font-weight: 800; color: var(--text); line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; outline: none; border-radius: 5px; padding: 2px 4px; margin: -2px -4px; }
  .flow-node .ftitle[contenteditable="true"] { background: rgba(255,255,255,0.08); box-shadow: 0 0 0 1px var(--neon); white-space: nowrap; }
  .flow-node .fsubtitle { font-size: 11px; font-weight: 500; color: var(--text-muted); line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .flow-node .fbody { position: relative; z-index: 2; margin-top: auto; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.06); display: flex; flex-direction: column; gap: 8px; }
  .flow-node .fmetric-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
  .flow-node .fmetric { display: flex; align-items: baseline; gap: 5px; }
  .flow-node .fmetric strong { font-size: 22px; font-weight: 800; color: var(--text); line-height: 1; letter-spacing: -0.02em; }
  .flow-node .fmetric span { font-size: 12px; font-weight: 600; color: var(--text-muted); }
  .flow-node .ftrend { font-size: 11px; font-weight: 700; padding: 3px 7px; border-radius: 999px; }
  .flow-node .ftrend.up { background: rgba(74,222,128,0.13); color: var(--neon-bright); border: 1px solid rgba(74,222,128,0.22); }
  .flow-node .ftrend.down { background: rgba(239,68,68,0.12); color: #f87171; border: 1px solid rgba(239,68,68,0.20); }

  .flow-node .fbadges { display: flex; flex-wrap: wrap; gap: 6px; }
  .flow-node .fbadge { font-size: 10px; font-weight: 800; padding: 4px 9px; border-radius: 999px; display: inline-flex; align-items: center; gap: 4px; border: 1px solid transparent; }
  .flow-node .fbadge.success { background: rgba(74,222,128,0.12); color: var(--neon-bright); border-color: rgba(74,222,128,0.22); }
  .flow-node .fbadge.fail { background: rgba(239,68,68,0.12); color: #f87171; border-color: rgba(239,68,68,0.20); }
  .flow-node .fbadge.info { background: rgba(59,130,246,0.12); color: #60a5fa; border-color: rgba(59,130,246,0.20); }
  .flow-node .fbadge.neutral { background: rgba(255,255,255,0.05); color: var(--text-muted); border-color: rgba(255,255,255,0.10); }

  /* Type themes */
  .flow-node.type-task { border-color: rgba(74,222,128,0.18); }
  .flow-node.type-task:hover { border-color: rgba(74,222,128,0.45); }
  .flow-node.type-task::before { background: radial-gradient(120% 80% at 20% 0%, rgba(74,222,128,0.13), transparent 60%); }
  .flow-node.type-task .ficon { background: linear-gradient(145deg, rgba(74,222,128,0.18), rgba(74,222,128,0.05)); color: var(--neon-bright); }

  .flow-node.type-plan { border-color: rgba(245,158,11,0.22); }
  .flow-node.type-plan:hover { border-color: rgba(245,158,11,0.48); }
  .flow-node.type-plan::before { background: radial-gradient(120% 80% at 20% 0%, rgba(245,158,11,0.14), transparent 60%); }
  .flow-node.type-plan .ficon { background: linear-gradient(145deg, rgba(245,158,11,0.18), rgba(245,158,11,0.05)); color: #fbbf24; }

  .flow-node.type-text { border-color: rgba(168,85,247,0.22); }
  .flow-node.type-text:hover { border-color: rgba(168,85,247,0.48); }
  .flow-node.type-text::before { background: radial-gradient(120% 80% at 20% 0%, rgba(168,85,247,0.13), transparent 60%); }
  .flow-node.type-text .ficon { background: linear-gradient(145deg, rgba(168,85,247,0.18), rgba(168,85,247,0.05)); color: #c084fc; }
  .flow-node.type-text .ftext { flex: 1; min-height: 70px; font-size: 12px; line-height: 1.6; color: var(--text-dim); outline: none; white-space: pre-wrap; word-break: break-word; }
  .flow-node.type-text .ftext:empty::before { content: '双击开始编辑...'; color: var(--text-muted); }
  .flow-node.type-text .ftext[contenteditable="true"] { background: rgba(255,255,255,0.05); border-radius: 8px; padding: 6px 8px; margin: -6px -8px; }

  .flow-node.type-image { border-color: rgba(59,130,246,0.22); }
  .flow-node.type-image:hover { border-color: rgba(59,130,246,0.48); }
  .flow-node.type-image::before { background: radial-gradient(120% 80% at 20% 0%, rgba(59,130,246,0.13), transparent 60%); }
  .flow-node.type-image .ficon { background: linear-gradient(145deg, rgba(59,130,246,0.18), rgba(59,130,246,0.05)); color: #93c5fd; }
  .flow-node.type-image .fimg { border-radius: 10px; overflow: hidden; min-height: 90px; display: grid; place-items: center; background: rgba(255,255,255,0.03); }
  .flow-node.type-image .fimg img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .flow-node.type-image .fimg .img-placeholder { color: var(--text-muted); }
  .flow-node.type-image .fimg .img-placeholder svg { width: 42px; height: 42px; opacity: .5; }

  .flow-node.type-ai { border-color: rgba(34,211,238,0.22); }
  .flow-node.type-ai:hover { border-color: rgba(34,211,238,0.48); }
  .flow-node.type-ai::before { background: radial-gradient(120% 80% at 20% 0%, rgba(34,211,238,0.14), transparent 60%); }
  .flow-node.type-ai .ficon { background: linear-gradient(145deg, rgba(34,211,238,0.18), rgba(168,85,247,0.10)); color: #67e8f9; }

  .flow-context-menu { position: fixed; display: none; min-width: 170px; padding: 6px; z-index: 200; border-radius: 12px; }
  .flow-context-menu.visible { display: block; animation: fadeIn .15s ease; }
  .flow-context-menu .cm-item { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 8px; font-size: 13px; color: var(--text-dim); cursor: pointer; transition: background .15s ease; }
  .flow-context-menu .cm-item:hover { background: var(--surface-hover); color: var(--text); }
  .flow-context-menu .cm-sep { height: 1px; background: var(--border); margin: 4px 6px; }

  /* Flow canvas fullscreen — covers the entire viewport and sits BEHIND the
     topbar and sidebars. The glass/glow-green outer frame is stripped so the
     canvas visually extends all the way to the chrome edges. */
  .project-flow-canvas.fullscreen {
    position: fixed;
    inset: 0;
    z-index: 2;
    margin: 0;
    border-radius: 0;
    max-width: none;
    background: var(--bg);
    border: none !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  .project-flow-canvas.fullscreen .flow-canvas-viewport { height: 100%; border-radius: 0; }
  /* When in fullscreen, the select bar is reparented to body so it
     can sit above the chrome while the canvas stays underneath. */
  .flow-select-bar.flow-fullscreen-floating {
    position: fixed;
    z-index: 30;
  }
  .flow-select-bar.flow-fullscreen-floating {
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
  }

  /* Selection action bar — appears when 2+ nodes are selected */
  .flow-select-bar {
    position: absolute;
    left: 50%;
    bottom: 18px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: 12px;
    background: rgba(14,14,18,0.92);
    border: 1px solid rgba(74,222,128,0.22);
    box-shadow: 0 18px 50px rgba(0,0,0,0.55);
    backdrop-filter: blur(12px);
    z-index: 60;
    font-size: 13px;
    color: var(--text);
    white-space: nowrap;
  }
  .flow-select-bar[hidden] { display: none; }
  .flow-select-bar .fsb-count { color: var(--text-muted); font-size: 12px; padding-right: 2px; }
  .flow-select-bar .fsb-group { color: #c4ff4d; border-color: rgba(196,255,77,0.4); font-weight: 700; }
  .flow-select-bar .fsb-group:hover { background: rgba(196,255,77,0.12); }
  .flow-select-bar .fsb-clear { color: var(--text-dim); }

  /* Bottom toolbar for the flow canvas */
  .flow-bottom-bar {
    position: absolute;
    left: 50%;
    bottom: 18px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 14px;
    background: rgba(14,14,18,0.92);
    border: 1px solid rgba(74,222,128,0.18);
    box-shadow: 0 18px 50px rgba(0,0,0,0.55);
    backdrop-filter: blur(14px);
    z-index: 60;
    font-size: 13px;
    color: var(--text);
    user-select: none;
  }
  .project-flow-canvas.fullscreen .flow-bottom-bar,
  .flow-bottom-bar.flow-fullscreen-floating {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    z-index: 30;
  }
  .fbb-left, .fbb-zoom { display: flex; align-items: center; gap: 6px; }
  .fbb-divider { width: 1px; height: 20px; background: rgba(255,255,255,0.10); margin: 0 2px; }
  .fbb-btn {
    width: 32px;
    height: 32px;
    border-radius: 9px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-dim);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: all .18s ease;
  }
  .fbb-btn svg { width: 16px; height: 16px; }
  .fbb-btn:hover { background: rgba(255,255,255,0.08); color: var(--text); }
  .fbb-btn.active { color: var(--neon-bright); background: rgba(74,222,128,0.12); border-color: rgba(74,222,128,0.25); }
  .fbb-zoom-value { min-width: 44px; text-align: center; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
  .fbb-zoom input[type="range"] {
    width: 96px;
    height: 4px;
    -webkit-appearance: none;
    appearance: none;
    background: rgba(255,255,255,0.12);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
  }
  .fbb-zoom input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--neon-bright);
    box-shadow: 0 0 8px rgba(74,222,128,0.45);
  }
  .fbb-zoom input[type="range"]::-moz-range-thumb {
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--neon-bright);
    border: none;
    box-shadow: 0 0 8px rgba(74,222,128,0.45);
  }
  /* Floating controls should not block drags passing over them */
  body.flow-dragging .flow-bottom-bar.flow-fullscreen-floating { pointer-events: none; opacity: .35; }

  /* Mini map */
  .flow-mini-map {
    position: fixed;
    right: 22px;
    bottom: 72px;
    width: 160px;
    height: 110px;
    border-radius: 10px;
    background: rgba(14,14,18,0.92);
    border: 1px solid rgba(74,222,128,0.18);
    box-shadow: 0 18px 50px rgba(0,0,0,0.55);
    backdrop-filter: blur(12px);
    z-index: 30;
    overflow: hidden;
    display: none;
  }
  .flow-mini-map.open { display: block; }
  .flow-mini-map canvas { width: 100%; height: 100%; }

  /* Custom edges — user-drawn flowchart connections */
  /* 电路板式连线：单条亮线（无边框）+ 辉光，圆角折线 */
  .flow-canvas-svg path.custom { fill: none; }
  .flow-canvas-svg path.custom.trace-line { stroke: rgba(74,222,128,0.85); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; filter: drop-shadow(0 0 3px rgba(74,222,128,0.5)); }
  .flow-canvas-svg path.custom.success.trace-line { stroke: #34d399; filter: drop-shadow(0 0 3px rgba(52,211,153,0.5)); }
  .flow-canvas-svg path.custom.fail.trace-line { stroke: rgba(239,68,68,0.85); filter: drop-shadow(0 0 3px rgba(239,68,68,0.45)); }
  .flow-canvas-svg path.custom.neutral.trace-line { stroke: rgba(148,163,184,0.78); filter: none; }
  /* 选中节点关联连线：变亮加粗 */
  .flow-canvas-svg path.custom.trace-line.sel { stroke: #6ee7a0; stroke-width: 3.2; filter: drop-shadow(0 0 6px rgba(74,222,128,0.85)); }
  .flow-canvas-svg path.custom.success.trace-line.sel { stroke: #6ee7b0; filter: drop-shadow(0 0 6px rgba(52,211,153,0.85)); }
  .flow-canvas-svg path.custom.fail.trace-line.sel { stroke: #f87171; stroke-width: 3.2; filter: drop-shadow(0 0 6px rgba(239,68,68,0.8)); }
  .fedge-label { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
  .fedge-label span {
    font-size: 10px; font-weight: 800; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
    background: rgba(30,34,42,0.92); border: 1px solid rgba(255,255,255,0.10);
    color: var(--text-dim); box-shadow: 0 4px 12px rgba(0,0,0,0.35);
    backdrop-filter: blur(6px);
  }
  .fedge-label.success span { background: rgba(74,222,128,0.13); color: var(--neon-bright); border-color: rgba(74,222,128,0.22); }
  .fedge-label.fail span { background: rgba(239,68,68,0.12); color: #f87171; border-color: rgba(239,68,68,0.20); }
  .fedge-label.neutral span { background: rgba(100,116,139,0.15); color: #94a3b8; border-color: rgba(100,116,139,0.22); }

  /* Flow groups */
  .flow-group {
    position: absolute;
    border-radius: 18px;
    background: rgba(74,222,128,0.04);
    border: 1px solid rgba(74,222,128,0.14);
    box-shadow: inset 0 0 30px rgba(74,222,128,0.04);
    z-index: 1;
    pointer-events: auto;
    cursor: grab;
    user-select: none;
  }
  .flow-group:active { cursor: grabbing; }
  .flow-group-header {
    position: absolute;
    top: -10px;
    left: 14px;
    padding: 3px 10px;
    border-radius: 6px;
    background: rgba(18,18,22,0.92);
    border: 1px solid rgba(74,222,128,0.22);
    color: var(--neon-bright);
    font-size: 11px;
    font-weight: 700;
    pointer-events: auto;
    cursor: context-menu;
    white-space: nowrap;
  }


/* 流程导图：上下/左右 切换按钮 */
.fbb-btn.fbb-layout { font-size: 11px; padding: 0 9px; letter-spacing: .03em; width: auto; height: 30px; }
.fbb-btn.fbb-layout.active { background: rgba(74,222,128,0.18); color: var(--neon-bright); border-color: rgba(74,222,128,0.5); font-weight: 700; }
.fbb-divider-v { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
html[data-theme="light"] .fbb-btn.fbb-layout.active { background: rgba(22,163,74,0.14); color: #15803d; border-color: rgba(22,163,74,0.4); }

/* 流程拖动对齐辅助线 */
.flow-align-guides { position: absolute; inset: 0; width: 4000px; height: 4000px; pointer-events: none; z-index: 6; overflow: visible; }
.flow-align-guides line.flow-guide { stroke: #4ade80; stroke-width: 1; stroke-dasharray: 5 4; opacity: .9; }

/* 连线箭头：实心纯色、无边框，颜色与连线类型一致 */
.flow-canvas-svg marker path, #flowSvg marker path { stroke: none; stroke-width: 0; }
.flow-canvas-svg marker#flowArrow path, #flowSvg marker#flowArrow path { fill: #4ade80; }
.flow-canvas-svg marker#flowArrowSuccess path, #flowSvg marker#flowArrowSuccess path { fill: #34d399; }
.flow-canvas-svg marker#flowArrowFail path, #flowSvg marker#flowArrowFail path { fill: #ef4444; }
.flow-canvas-svg marker#flowArrowNeutral path, #flowSvg marker#flowArrowNeutral path { fill: #94a3b8; }
.flow-canvas-svg marker#flowArrowSel path, #flowSvg marker#flowArrowSel path { fill: #6ee7a0; }
.flow-canvas-svg marker#flowArrowSuccessSel path, #flowSvg marker#flowArrowSuccessSel path { fill: #6ee7b0; }
.flow-canvas-svg marker#flowArrowFailSel path, #flowSvg marker#flowArrowFailSel path { fill: #f87171; }
.flow-canvas-svg marker#flowArrowDone path, #flowSvg marker#flowArrowDone path { fill: #3b82f6; }
