/* ============================================================
   graph.css — 图谱页专属样式（F6 桌面 / F7 移动端）
   命名一律 gx- 前缀：与 style.css 里遗留的 .graph-* 规则完全不相交，
   避免 @media(max-width:760px) 那条 .graph-panel{overflow-x:auto} 复活横向滚动。
   ============================================================ */

:root {
  /* style.css 已定义这批变量；此处仅作独立打开 graph.html 时的兜底。 */
  --gx-l1: var(--l1, #7d3829);
  --gx-l2: var(--l2, #b85d3d);
  --gx-l3: var(--l3, #d28a62);
  --gx-l4: var(--l4, #927056);
  --gx-l5: var(--l5, #6c7c5b);
  --gx-ink: var(--ink, #3a2f24);
  --gx-ink-soft: var(--ink-soft, #6b5b48);
  --gx-ink-light: var(--ink-light, #9b8871);
  --gx-accent: var(--accent, #b85d3d);
  --gx-accent-dark: var(--accent-dark, #8f3f2b);
  --gx-accent-light: var(--accent-light, #f8e9e1);
  --gx-bg: var(--bg, #fbf6ef);
  --gx-card: var(--bg-card, #fffdf9);
  --gx-border: var(--border, #e6d9c7);
  --gx-border-strong: var(--border-strong, #d4c4ad);
  --gx-contrast: #b2402f;
  --gx-edge: #8d7a63;
  --gx-label: 12.5px;
}

/* 页面骨架：图谱页要更宽的主区；侧栏未注入时（独立打开）自动收掉左边距 */
body[data-page="graph"] .main { max-width: 1520px; padding: 26px 30px 26px; }
body[data-page="graph"]:not(:has(.sidebar)) .main { margin-left: 0; }
body[data-page="graph"] .gx-head { max-width: 820px; margin-bottom: 14px; }
body[data-page="graph"] .gx-head h1 { font-size: clamp(26px, 3vw, 38px); }
body[data-page="graph"] .gx-head p { margin-top: 8px; font-size: 14px; }

/* 详情默认浮在画布右上角：全站侧栏一占 288px，再切一列 340px 给面板，
   画布就只剩 ~730px，五层带会被压到 0.67 倍、标签掉到 8px。宽屏才分两栏。 */
.gx { position: relative; }

/* ---------- 舞台 ---------- */
.gx-stage {
  display: flex; flex-direction: column; min-width: 0;
  height: clamp(460px, calc(100vh - 190px), 1080px);
  border: 1px solid var(--gx-border);
  background: var(--gx-card);
}
@supports (height: 100dvh) {
  .gx-stage { height: clamp(460px, calc(100dvh - 190px), 1080px); }
}

.gx-toolbar { flex: 0 0 auto; border-bottom: 1px solid var(--gx-border); }
.gx-toolbar-top {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px;
}
.gx-status { min-width: 0; color: var(--gx-ink-soft); font-size: 12px; font-variant-numeric: tabular-nums; }
.gx-status b { color: var(--gx-ink); font-weight: 600; }
.gx-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.gx-zoom { display: inline-flex; gap: 4px; }

.gx-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 30px; padding: 4px 11px;
  border: 1px solid var(--gx-border-strong); border-radius: 6px;
  background: var(--gx-card); color: var(--gx-ink-soft);
  font-size: 12px; line-height: 1; white-space: nowrap; cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.gx-btn:hover { border-color: var(--gx-accent); color: var(--gx-accent); }
.gx-btn:focus-visible { outline: 2px solid var(--gx-accent); outline-offset: 2px; }
.gx-btn-icon { width: 30px; padding: 0; font-size: 15px; }
.gx-filter-toggle[aria-expanded="true"] { border-color: var(--gx-accent); background: var(--gx-accent-light); color: var(--gx-accent-dark); }

/* ---------- 筛选 ---------- */
.gx-filters {
  display: grid; grid-template-columns: 54px minmax(0, 1fr);
  gap: 3px 10px; align-items: start;
  padding: 0 12px 10px;
}
.gx-filters.is-collapsed { display: none; }
.gx-fset { display: contents; }
.gx-fset-title {
  padding-top: 6px;
  color: var(--gx-ink-light); font-size: 10px; letter-spacing: .16em;
}
.gx-chips { display: flex; flex-wrap: wrap; gap: 5px; padding-bottom: 1px; }
/* 筛选条由 JS 按真实计数生成：没 JS / 还没生成时不要留一排空标题 */
.gx-chips:empty { display: none; }
.gx-fset:has(.gx-chips:empty) .gx-fset-title { display: none; }
.gx-chip {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 25px; padding: 2px 9px;
  border: 1px solid var(--gx-border); border-radius: 99px;
  background: var(--gx-card); color: var(--gx-ink-soft);
  font-size: 11.5px; line-height: 1.3; cursor: pointer;
  user-select: none;
  transition: border-color .15s ease, background .15s ease, opacity .15s ease;
}
.gx-chip input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.gx-chip:hover { border-color: var(--gx-border-strong); }
.gx-chip:focus-within { outline: 2px solid var(--gx-accent); outline-offset: 1px; }
.gx-chip em { color: var(--gx-ink-light); font-size: 10px; font-style: normal; font-variant-numeric: tabular-nums; }
.gx-chip.is-off { opacity: .42; background: transparent; text-decoration: line-through; text-decoration-thickness: 1px; }
.gx-chip-btn { color: var(--gx-accent-dark); }
.gx-chip-swatch { width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; }
.gx-chip-glyph { width: 13px; height: 13px; flex: 0 0 auto; fill: var(--gx-ink-soft); }
.gx-chip-line { width: 22px; height: 8px; flex: 0 0 auto; }
.gx-chip-line line { stroke-width: 1.6; }
.gx-chip-line path { fill: currentColor; }

/* ---------- 画布 ---------- */
.gx-viewport {
  position: relative;
  flex: 1 1 auto; min-height: 0;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(255,253,249,0) 88%, rgba(246,238,227,.7) 100%),
    var(--gx-card);
  touch-action: none;
  overscroll-behavior: contain;
}
#gx-canvas { display: block; width: 100%; height: 100%; cursor: grab; }
#gx-canvas.is-panning { cursor: grabbing; }
#gx-canvas:focus-visible { outline: 2px solid var(--gx-accent); outline-offset: -2px; }

/* 层带 */
.gx-band-bg { stroke-width: 1; }
.gx-band-1 { fill: #f5ece9; fill: color-mix(in srgb, var(--gx-l1) 7%, transparent); stroke: #f0ded9; stroke: color-mix(in srgb, var(--gx-l1) 18%, transparent); }
.gx-band-2 { fill: #faeee9; fill: color-mix(in srgb, var(--gx-l2) 7%, transparent); stroke: #f3ded4; stroke: color-mix(in srgb, var(--gx-l2) 18%, transparent); }
.gx-band-3 { fill: #fbf1ea; fill: color-mix(in srgb, var(--gx-l3) 8%, transparent); stroke: #f5e3d6; stroke: color-mix(in srgb, var(--gx-l3) 20%, transparent); }
.gx-band-4 { fill: #f6f1ea; fill: color-mix(in srgb, var(--gx-l4) 8%, transparent); stroke: #ece2d4; stroke: color-mix(in srgb, var(--gx-l4) 20%, transparent); }
.gx-band-5 { fill: #f0f2ec; fill: color-mix(in srgb, var(--gx-l5) 8%, transparent); stroke: #e2e7db; stroke: color-mix(in srgb, var(--gx-l5) 20%, transparent); }
.gx-band-num { font-family: Georgia, "Songti SC", serif; font-size: 17px; font-weight: 600; letter-spacing: .02em; }
.gx-band-name { font-size: 11.5px; }
.gx-band-meta { font-size: 10.5px; fill: var(--gx-ink-light); }
.gx-band-num.l1 { fill: var(--gx-l1); }
.gx-band-num.l2 { fill: var(--gx-l2); }
.gx-band-num.l3 { fill: #b06a3f; }
.gx-band-num.l4 { fill: var(--gx-l4); }
.gx-band-num.l5 { fill: var(--gx-l5); }
.gx-band-name { fill: var(--gx-ink-soft); }
.gx-band.is-collapsed { cursor: pointer; }
.gx-band.is-collapsed .gx-band-bg:hover { stroke: var(--gx-accent); }
.gx-band.is-hidden .gx-band-bg { fill: transparent; stroke-dasharray: 3 4; }
.gx-band.is-hidden .gx-band-num, .gx-band.is-hidden .gx-band-name { opacity: .4; }

/* 边 */
.gx-edge { fill: none; stroke: var(--gx-edge); stroke-opacity: .32; stroke-linecap: round; pointer-events: none; }
.gx-edge-INFERS { stroke: var(--gx-accent); stroke-opacity: .46; marker-end: url(#gx-arrow); }
.gx-edge-CONTRASTS { stroke: var(--gx-contrast); stroke-opacity: .58; stroke-dasharray: 5 3.5; }
.gx-edge-EXEMPLIFIES { stroke: #6c7c5b; stroke-opacity: .45; stroke-dasharray: 1.6 3.4; }
.gx-edge-RELATES_TO { stroke: #a89a86; stroke-opacity: .28; }
.gx-edge-hit { fill: none; stroke: transparent; stroke-width: 11; cursor: pointer; }

/* 节点 */
.gx-node { cursor: pointer; }
.gx-node .gx-shape { stroke: #fffdf9; stroke-width: 1.3; }
.gx-node .gx-label {
  fill: var(--gx-ink-soft); font-size: var(--gx-label);
  text-anchor: middle; pointer-events: none;
  paint-order: stroke; stroke: rgba(255,253,249,.92); stroke-width: 3px; stroke-linejoin: round;
}
.gx-node:focus { outline: none; }
.gx-node:focus-visible .gx-shape { stroke: var(--gx-accent-dark); stroke-width: 2.4; }
.gx-node:hover .gx-label { fill: var(--gx-ink); }
.gx-l1 { fill: var(--gx-l1); }
.gx-l2 { fill: var(--gx-l2); }
.gx-l3 { fill: var(--gx-l3); }
.gx-l4 { fill: var(--gx-l4); }
.gx-l5 { fill: var(--gx-l5); }

/* 过滤：真隐藏 */
.gx-off { display: none; }
/* 缩得太小时收标签：任何可见标签都保证 ≥11px（阈值见 graph.js 的 pushView） */
.gx-root.no-labels .gx-label { display: none; }

/* 聚焦态：hover / 选中 时淡化无关元素 */
/* 用 opacity（不是 stroke-opacity）淡化边：marker 箭头才会跟着一起淡下去 */
.gx-root.is-focus .gx-node { opacity: .13; transition: opacity .12s ease; }
.gx-root.is-focus .gx-edge { opacity: .07; }
.gx-root.is-focus .gx-node.is-hot { opacity: 1; }
.gx-root.is-focus .gx-edge.is-hot { opacity: 1; stroke-opacity: .85; stroke-width: 2; }
.gx-root .gx-node.is-sel .gx-shape { stroke: var(--gx-ink); stroke-width: 2.2; }
.gx-root .gx-node.is-sel .gx-label { fill: var(--gx-ink); font-weight: 600; }
.gx-root .gx-node.is-path .gx-shape { stroke: var(--gx-ink); stroke-width: 1.9; }
.gx-root .gx-edge.is-path { opacity: 1; stroke: var(--gx-accent-dark); stroke-opacity: .95; stroke-width: 2.2; }
.gx-root .gx-edge.is-path.gx-edge-INFERS { marker-end: url(#gx-arrow-hot); }
.gx-root.is-dragging .gx-node { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .gx-root.is-focus .gx-node { transition: none; }
  .gx-btn, .gx-chip { transition: none; }
}

/* 悬停提示 */
.gx-tip {
  position: absolute; z-index: 6; max-width: 260px;
  padding: 7px 10px;
  border: 1px solid var(--gx-border-strong); border-radius: 7px;
  background: rgba(255,253,249,.97);
  box-shadow: 0 6px 18px rgba(58,47,36,.14);
  color: var(--gx-ink); font-size: 12px; line-height: 1.5;
  pointer-events: none;
}
.gx-tip[hidden] { display: none; }
.gx-tip b { display: block; margin-bottom: 2px; font-size: 10px; font-weight: 600; letter-spacing: .1em; }
.gx-tip .gx-tip-pair { color: var(--gx-ink-soft); font-size: 11px; }
.gx-tip-SUPPORTS b { color: var(--gx-edge); }
.gx-tip-INFERS b { color: var(--gx-accent); }
.gx-tip-CONTRASTS b { color: var(--gx-contrast); }
.gx-tip-EXEMPLIFIES b { color: #5f6f50; }
.gx-tip-RELATES_TO b { color: var(--gx-ink-light); }

.gx-hint {
  position: absolute; right: 10px; bottom: 8px; z-index: 4;
  margin: 0; padding: 3px 9px;
  border-radius: 99px; background: rgba(255,253,249,.86);
  color: var(--gx-ink-light); font-size: 11px;
  pointer-events: none;
  transition: opacity .45s ease;
}
.gx-hint.is-gone { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .gx-hint { transition: none; } }
/* 只给 p.gx-noscript 定位，不碰 <noscript> 本身：给 noscript 设 display 会让它在开了 JS 时也显形 */
.gx-noscript {
  position: absolute; inset: 0; z-index: 3;
  margin: 0; padding: 28px;
  background: var(--gx-card);
  color: var(--gx-ink-soft); font-size: 14px; line-height: 1.8;
}
.gx-noscript a { color: var(--gx-accent); }

/* ---------- 常驻图例 ---------- */
.gx-legend {
  flex: 0 0 auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  padding: 8px 12px;
  border-top: 1px solid var(--gx-border);
  background: #fdf9f3;
  color: var(--gx-ink-soft); font-size: 11.5px;
}
.gx-legend-title { color: var(--gx-ink-light); font-size: 10px; letter-spacing: .16em; }
.gx-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.gx-legend-item svg { width: 26px; height: 10px; overflow: visible; }
.gx-legend-item[data-kind] svg { width: 13px; height: 13px; }
.gx-legend-item line { stroke-width: 1.7; }
.gx-legend-item[data-edge="SUPPORTS"] line { stroke: var(--gx-edge); }
.gx-legend-item[data-edge="INFERS"] line { stroke: var(--gx-accent); }
.gx-legend-item[data-edge="INFERS"] path { fill: var(--gx-accent); }
.gx-legend-item[data-edge="CONTRASTS"] line { stroke: var(--gx-contrast); }
.gx-legend-item[data-edge="EXEMPLIFIES"] line { stroke: #6c7c5b; }
.gx-legend-item[data-kind] svg * { fill: var(--gx-ink-soft); }
.gx-legend-sep { width: 1px; height: 14px; background: var(--gx-border-strong); }

/* ---------- 详情面板 ---------- */
.gx-detail {
  position: absolute; z-index: 20; top: 10px; right: 10px;
  display: none; width: 318px; max-height: calc(100% - 20px); overflow-y: auto;
  padding: 16px;
  border: 1px solid var(--gx-border-strong); background: var(--gx-card);
  box-shadow: 0 10px 30px rgba(58, 47, 36, .16);
}
.gx-detail.is-filled { display: block; }
@media (min-width: 1560px) {
  .gx { display: grid; grid-template-columns: minmax(0, 1fr) 344px; gap: 16px; align-items: start; }
  .gx-detail {
    position: sticky; display: block; top: 20px; right: auto; width: auto;
    max-height: calc(100vh - 40px); padding: 18px;
    border-color: var(--gx-border); box-shadow: none;
  }
}
.gx-detail-grip { display: none; }
.gx-detail-close {
  position: absolute; top: 10px; right: 10px;
  display: none; width: 30px; height: 30px;
  border: 1px solid var(--gx-border); border-radius: 50%;
  background: var(--gx-card); color: var(--gx-ink-soft);
  font-size: 17px; line-height: 1; cursor: pointer;
}
.gx-detail.is-filled .gx-detail-close { display: block; }
.gx-detail-close:hover { border-color: var(--gx-accent); color: var(--gx-accent); }
.gx-empty { color: var(--gx-ink-soft); font-size: 13px; }
.gx-empty-title { margin: 0 0 6px; color: var(--gx-ink); font-size: 15px; font-weight: 600; }
.gx-empty p { margin: 0 0 8px; line-height: 1.7; }

.gx-d-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; font-size: 11px; }
.gx-d-layer { padding: 2px 7px; border-radius: 99px; color: #fff; font-weight: 600; letter-spacing: .04em; }
.gx-d-kind { color: var(--gx-ink-light); }
.gx-detail h2 { margin: 0 0 8px; padding-right: 26px; font-family: Georgia, "Songti SC", serif; font-size: 22px; line-height: 1.3; }
.gx-d-lede { margin: 0 0 12px; color: var(--gx-ink-soft); font-size: 13.5px; line-height: 1.7; }
.gx-d-callout {
  margin: 0 0 12px; padding: 9px 11px;
  border-left: 3px solid var(--gx-accent); background: var(--gx-accent-light);
  color: var(--gx-ink-soft); font-size: 12.5px; line-height: 1.65;
}
.gx-d-callout strong { color: var(--gx-accent-dark); }
.gx-d-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0 0 12px; }
.gx-d-facts div { padding: 7px 8px; border: 1px solid var(--gx-border); }
.gx-d-facts dt { color: var(--gx-ink-light); font-size: 10px; }
.gx-d-facts dd { margin: 2px 0 0; font-family: Georgia, serif; font-size: 17px; }
.gx-d-actions { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }
.gx-d-actions .gx-btn.is-primary { border-color: var(--gx-accent); background: var(--gx-accent); color: #fff; }
.gx-d-actions .gx-btn.is-primary:hover { background: var(--gx-accent-dark); color: #fff; }
.gx-d-path {
  margin: 0 0 14px; padding: 9px 11px;
  border: 1px dashed var(--gx-border-strong); background: #fdf7f0;
  color: var(--gx-ink-soft); font-size: 12px; line-height: 1.65;
}
.gx-d-path b { color: var(--gx-ink); }

.gx-d-group { margin-top: 14px; padding-top: 11px; border-top: 1px solid var(--gx-border); }
.gx-d-group h3 {
  display: flex; align-items: baseline; gap: 6px; margin: 0 0 7px;
  color: var(--gx-ink); font-size: 12px; font-weight: 600; letter-spacing: .04em;
}
.gx-d-group h3 em { color: var(--gx-ink-light); font-size: 10.5px; font-style: normal; font-weight: 400; }
.gx-d-list { margin: 0; padding: 0; list-style: none; }
.gx-d-list li { display: flex; align-items: flex-start; gap: 4px; padding: 4px 0; border-bottom: 1px dashed rgba(214,196,173,.5); }
.gx-d-list li:last-child { border-bottom: 0; }
.gx-rel { flex: 1 1 auto; min-width: 0; display: block; color: inherit; text-decoration: none; }
.gx-rel:hover .gx-rel-name { color: var(--gx-accent); text-decoration: underline; }
.gx-rel-name { display: flex; align-items: center; gap: 5px; font-size: 12.5px; line-height: 1.5; }
.gx-rel-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.gx-rel-note { display: block; margin-top: 1px; color: var(--gx-ink-light); font-size: 11px; line-height: 1.5; }
.gx-locate {
  flex: 0 0 auto; width: 24px; height: 24px; margin-top: 1px;
  border: 1px solid transparent; border-radius: 6px;
  background: transparent; color: var(--gx-ink-light);
  font-size: 12px; line-height: 1; cursor: pointer;
}
.gx-locate:hover { border-color: var(--gx-border-strong); color: var(--gx-accent); }
.gx-d-sources { margin: 12px 0 0; padding: 10px 0 0; border-top: 1px solid var(--gx-border); color: var(--gx-ink-light); font-size: 11px; }
.gx-d-sources li { margin-bottom: 3px; line-height: 1.5; }
.gx-d-sources ul { margin: 5px 0 0; padding-left: 16px; }

/* ---------- F7 移动端 ---------- */
@media (max-width: 760px) {
  body[data-page="graph"] .main { margin-left: 0; padding: 58px 12px 16px; max-width: 100%; }
  body[data-page="graph"] .gx-head { margin-bottom: 12px; }
  body[data-page="graph"] .gx-head h1 { font-size: 27px; }
  body[data-page="graph"] .gx-head p { margin-top: 6px; font-size: 13px; line-height: 1.6; }

  .gx-stage {
    border-left: 0; border-right: 0; margin: 0 -12px;
    height: clamp(380px, calc(100vh - 262px), 900px);
  }
  @supports (height: 100dvh) {
    .gx-stage { height: clamp(380px, calc(100dvh - 262px), 900px); }
  }
  .gx-toolbar-top { padding: 7px 10px; gap: 8px; }
  .gx-status { font-size: 11.5px; }
  .gx-btn { min-height: 34px; padding: 4px 12px; }
  .gx-btn-icon { width: 34px; }

  /* 筛选默认收起，点「筛选」展开 —— 小屏不让工具条吃掉画布 */
  .gx-filters, .gx-filters.is-collapsed { display: none; grid-template-columns: 44px minmax(0, 1fr); padding: 0 10px 8px; }
  .gx-filters.is-open { display: grid; }
  .gx-chip { min-height: 32px; padding: 4px 10px; font-size: 12px; }

  /* 小屏图例只留四类关系：节点形状在筛选条里已经带图标，重复一遍不值一行高度 */
  .gx-legend { gap: 5px 12px; padding: 7px 10px; font-size: 11px; }
  .gx-legend-item[data-kind], .gx-legend-sep { display: none; }
  .gx-hint { display: none; }

  /* 详情 = 底部抽屉 */
  .gx-detail {
    position: fixed; z-index: 60; inset: auto 0 0 0; top: auto;
    width: auto; max-height: min(66vh, 520px);
    padding: 14px 16px calc(18px + env(safe-area-inset-bottom));
    border: 0; border-top: 1px solid var(--gx-border-strong);
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -10px 30px rgba(58,47,36,.18);
    transform: translateY(102%);
    transition: transform .22s ease;
    visibility: hidden;
  }
  .gx-detail.is-open { transform: none; visibility: visible; }
  .gx-detail-grip { display: block; width: 38px; height: 4px; margin: 0 auto 10px; border-radius: 99px; background: var(--gx-border-strong); }
  .gx-detail-close { display: block; top: 8px; right: 12px; width: 34px; height: 34px; }
  .gx-detail:not(.is-filled) { display: none; }
  .gx-d-facts { grid-template-columns: repeat(3, 1fr); }
  .gx-locate { width: 32px; height: 32px; }
  .gx-d-list li { padding: 6px 0; }
}
@media (max-width: 760px) and (prefers-reduced-motion: reduce) {
  .gx-detail { transition: none; }
}
