/* ==================================================================
   mindmap5.3 · canvas.css —— 画布 / 连线层 / 视口
   ================================================================== */
html, body { height: 100%; }
/* 双指横向平移留在脑图内，阻止浏览器越界前进 / 后退手势。 */
html, body, #stage { overscroll-behavior-x: none; }
body {
  font-family: var(--font-ui);
  color: var(--text-0);
  background: linear-gradient(180deg, var(--bg-0), var(--bg-1));
  overflow: hidden;
}

#menubar { position: fixed; top: 0; left: 0; right: 0; height: var(--menubar-h); z-index: var(--z-menubar); }

#stage {
  position: fixed; inset: var(--menubar-h) 0 0 0;
  overflow: hidden; cursor: grab;
  background: var(--board-bg-active);
  transition: right var(--anim), background var(--anim);
  touch-action: none;
}
body.reader-mode-split #stage { right: var(--reader-right-inset); }
body.reader-mode-reader-only #stage { visibility: hidden; pointer-events: none; }
body.reader-resizing #stage { transition: none; }
#stage.panning { cursor: grabbing; }
#stage.marquee-selecting { cursor: crosshair; }
#stage.grid-on { background-image: var(--board-grid), var(--board-bg-active); }
#stage.picking { cursor: crosshair; }

#vp { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-origin: 0 0; }
#nodes-layer, #wires-layer { position: absolute; left: 0; top: 0; overflow: visible; }
#wires-layer { z-index: 1; pointer-events: none; }
#nodes-layer { z-index: 2; }
.selection-marquee {
  position: fixed; z-index: 20; display: none; pointer-events: none;
  border: 1px solid var(--sel-ring); border-radius: 5px;
  background: color-mix(in srgb, var(--sel-ring) 13%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sel-ring) 22%, transparent) inset;
}
.selection-marquee.show { display: block; }

/* 连线原点必须与节点层一致，不能让行内 SVG 的文字基线产生纵向偏移。 */
svg.wires { display: block; overflow: visible; width: 10px; height: 10px; }
.wire { fill: none; stroke-width: 1.8; opacity: .9; }
.wire-soft { fill: none; stroke-width: 4.5; opacity: .16; stroke-linecap: round; }
.wire-organic { stroke: none; opacity: var(--elegant-link-opacity, .9); }
.wire-centerline { visibility: hidden; }
.brace { fill: none; stroke: var(--lv-sum, #e879f9); stroke-width: 2.2; stroke-linecap: round; }
.brace-soft { fill: none; stroke: var(--lv-sum, #e879f9); stroke-width: 7; opacity: .15; stroke-linecap: round; }
.selection-summary-preview {
  fill: none; stroke: var(--sel-ring); stroke-width: 2.5; stroke-dasharray: 6 5;
  stroke-linecap: round; opacity: .92; pointer-events: none;
  vector-effect: non-scaling-stroke;
}
.relation { fill: none; stroke: var(--rel-line); stroke-width: 1.8; stroke-dasharray: 6 5; cursor: pointer; pointer-events: stroke; }
.relation:hover { stroke-width: 2.6; }
.relation.selected {
  stroke-width: 3.2; stroke-dasharray: none;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--rel-line) 80%, transparent));
}
/* 关系线命中辅助路径：透明加宽热区，仅扩大点击范围，不参与选中发光 */
.relation-hit { fill: none; stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }
/* 悬停热区时联动可见线加粗（hit 与可见线为相邻兄弟） */
.relation-hit:hover + .relation { stroke-width: 2.6; }
.rel-label { font: 600 10.5px var(--font-ui); fill: var(--rel-line); letter-spacing: .08em; pointer-events: auto; cursor: pointer; }
.rel-label-bg { fill: var(--board-solid, #081020); stroke: var(--rel-line); stroke-opacity: .55; pointer-events: auto; cursor: pointer; }
html[data-theme="light"] .rel-label-bg { fill: #f6fafe; }
.circuit-dot { fill: var(--ac, #2dd4bf); }

body.measuring .ic-card,
body.measuring .ic-card *,
.ic-card.measuring,
.ic-card.measuring * { transition: none !important; animation: none !important; }

/* 空状态提示 */
#hint {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  font-size: 12px; color: var(--text-2); letter-spacing: .1em;
  background: var(--panel-bg); border: 1px solid var(--panel-border);
  padding: 7px 16px; border-radius: 999px; backdrop-filter: blur(8px);
  z-index: 5; pointer-events: none; transition: opacity .4s; white-space: nowrap;
}
#hint.hide { opacity: 0; }

/* 雅致只覆盖 theme 画布；明确的用户背景预设与科技画布保持旧路径。 */
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"])[data-background="theme"] #stage {
  background: var(--elegant-canvas);
}
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"])[data-background="theme"] #stage.grid-on {
  background-image: radial-gradient(var(--elegant-dot-color) var(--elegant-dot-radius), transparent var(--elegant-dot-radius));
  background-size: var(--elegant-dot-spacing) var(--elegant-dot-spacing);
}
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"]) #wire-svg .wire { stroke-width: var(--elegant-link-width); opacity: var(--elegant-link-opacity); }
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"]) #wire-svg .wire-soft { opacity: .08; }
/* 关系仍保留双向箭头与虚线语义，只协调默认色；仅在雅致连线层局部覆盖。 */
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"]) #wire-svg { --rel-line: var(--ui-color-5); }
html:is([data-map-style="elegant"], [data-map-style="ink"], [data-map-style="compact"], [data-map-style^="ribbon"])[data-background="theme"] #wire-svg .rel-label-bg { fill: var(--elegant-canvas); }

/* 首屏排版中继续测量真实尺寸，但不展示中间位置或启动过渡。 */
/* 隐藏初始投影但保留几何测量，避免大图在恢复期间反复绘制不可见卡片。 */
body.map-loading #vp { visibility: hidden; opacity: 0; pointer-events: none; }
body.map-loading #vp, body.map-loading #vp * { transition: none !important; animation: none !important; }
#map-loading {
  position: absolute; inset: 0; z-index: 3; display: grid; place-items: center;
  color: var(--ui-muted); font: var(--ui-font-size)/var(--ui-line-height) var(--ui-font);
  cursor: progress; pointer-events: auto;
}
#map-loading[hidden] { display: none; }
