:root{
  --paper:#f4f6f9;
  --white:#fff;
  --ink:#141d26;
  --ink-soft:#43505d;
  --muted:#6b7784;
  --line:#c7d0d9;
  --line-soft:#e3e8ed;
  --blue:#1462d5;
  --blue-soft:#e8f0ff;
  --green:#0a7d6f;
  --green-soft:#e4f4f1;
  --orange:#d64a15;
  --orange-soft:#fff0e8;
  --yellow:#a86f00;
  --yellow-soft:#fff5d6;
  --purple:#6435c9;
  --purple-soft:#efeaff;
  --dark:#0e1620;
  --shadow:0 10px 30px rgba(20,29,38,.10);
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",Arial,sans-serif;
  --mono:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;color:var(--ink);background:var(--paper);font:400 16px/1.65 var(--sans);overflow-x:hidden}
.wrap{width:min(1400px,calc(100% - clamp(40px,6vw,110px)));margin-inline:auto}
.anchor{position:relative;height:0}

/* ---------- progress rail ---------- */
.rail{
  position:fixed;top:0;left:0;right:0;z-index:70;
  background:rgba(14,22,32,.95);color:#fff;
  display:flex;align-items:center;gap:22px;
  padding:0 clamp(20px,3vw,44px);min-height:54px;
}
.rail::before{
  content:"GraphRAG 端到端流程";font:700 13.5px/1.4 var(--mono);color:#fff;white-space:nowrap;
}
.rail-bar{position:absolute;left:0;bottom:0;height:3px;width:100%;background:#243141}
.rail-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,#1462d5,#28b3a0)}
.rail-acts{display:flex;gap:6px;margin-left:auto}
.rail-acts button{
  padding:7px 15px;background:none;border:1px solid #33414f;color:#b6c1cd;
  font:600 13.5px/1.4 var(--sans);cursor:pointer;
}
.rail-acts button:hover{background:#1462d5;border-color:#1462d5;color:#fff}

/* ---------- intro ---------- */
.intro{padding:150px 0 120px;background:var(--dark);color:#fff}
.eyebrow{margin:0 0 16px;color:#7fb2ff;font:700 13.5px/1.3 var(--mono)}
.intro h1{margin:0;max-width:20em;font-size:clamp(32px,3.6vw,52px);line-height:1.16;font-weight:760}
.intro .lede{max-width:62em;margin:22px 0 0;color:#bcc7d3;font-size:clamp(16px,1.25vw,19px)}
.intro .lede2{margin-top:14px;color:#8fa3b8;font-size:clamp(15px,1.15vw,17px)}
.intro .lede2 strong{color:#cfdcea;font-weight:730}
.scrollcue{margin-top:52px;display:flex;align-items:center;gap:14px;color:#8b98a6;font:600 13.5px/1 var(--mono)}
.scrollcue i{
  display:block;width:2px;height:44px;
  background:linear-gradient(#5aa2ff,rgba(90,162,255,0));
  animation:cue 1.7s ease-in-out infinite;
}
@keyframes cue{0%,100%{transform:translateY(0);opacity:1}50%{transform:translateY(10px);opacity:.35}}

/* ---------- pinned DAG scene ---------- */
.dagscene{position:relative;background:var(--paper)}
.dagstage{
  position:relative;height:100vh;overflow:hidden;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
}
/* 上半：图；下半：解说条（互不遮挡） */
.dagcanvas{position:absolute;left:0;right:0;top:54px;bottom:var(--footH,208px)}
.dagcanvas svg{display:block;width:100%;height:100%}
.dagfoot{
  position:absolute;left:0;right:0;bottom:0;height:var(--footH,208px);
  display:flex;align-items:stretch;gap:0;
  background:#fff;border-top:2px solid var(--ink);
}

.n-box{cursor:pointer}
.n-box .nb{transition:filter .18s}
.n-box:hover .nb{filter:drop-shadow(0 5px 14px rgba(0,0,0,.26))}
.n-box.static{cursor:default}
.e-path{cursor:pointer}
.e-path:hover .ehit{stroke-opacity:.14}

/* beat copy strip */
.beat{
  flex:1 1 auto;min-width:0;display:grid;
  grid-template-columns:auto minmax(0,1fr) minmax(0,.72fr);
  align-items:start;gap:22px;
  padding:20px clamp(20px,3vw,44px);border-left:7px solid var(--blue);
}
.beat-i{display:flex;flex-direction:column;align-items:center;gap:8px;padding-top:3px}
.beat-i span{
  display:grid;place-items:center;width:38px;height:38px;
  background:var(--blue);color:#fff;font:800 15px/1 var(--mono);
}
.beat-i em{
  font:800 13px/1.3 var(--mono);color:var(--blue);font-style:normal;
  writing-mode:vertical-rl;letter-spacing:.08em;
}
.beat-tx{min-width:0}
.beat h2{margin:0 0 7px;font-size:clamp(19px,1.65vw,25px);line-height:1.28;font-weight:750}
.beat p{margin:0;color:var(--ink-soft);font-size:15.5px;line-height:1.66}
.beat-fact{
  padding:12px 15px;background:var(--yellow-soft);
  border-left:4px solid var(--yellow);color:#6b4700;font:600 13.5px/1.62 var(--sans);
}
.beat-fact:empty{display:none}

/* minimap */
.minimap{
  flex:0 0 auto;align-self:center;width:284px;padding:12px 14px;
  margin-right:clamp(16px,2.4vw,34px);
  background:#fbfcfd;border:1px solid var(--line);
}
.minimap svg{display:block;width:100%;height:auto}

.taphint{
  position:absolute;right:clamp(20px,3vw,46px);top:calc(54px + 20px);
  padding:8px 14px;background:var(--ink);color:#fff;
  font:700 13px/1.4 var(--mono);opacity:0;transition:opacity .4s;
}
.taphint.on{opacity:.9}

/* ---------- agentic cycle ---------- */
.cyclescene{padding:96px 0 100px;background:var(--dark);color:#fff}
.cyclestage{width:min(1400px,calc(100% - clamp(40px,6vw,110px)));margin-inline:auto}
.eyebrow2{margin:0 0 14px;color:#5ad2be;font:700 13.5px/1.3 var(--mono)}
.cyclehead h2{margin:0;max-width:22em;font-size:clamp(26px,2.7vw,38px);line-height:1.22;font-weight:760}
.cyclehead p{max-width:64em;margin:16px 0 0;color:#b9c4d0;font-size:clamp(15.5px,1.2vw,18px)}
.cyclehead strong{color:#fff;font-weight:750}
.cyclebody{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:34px;margin-top:44px;align-items:start}
/* 图跟着走：展开多张卡片后面板高达 2900px，静态定位会让环形图滚出屏幕，
   右侧的「第 5 轮」「第 6 轮」就失去了参照物 —— 而这张图的意义就是标出当前轮在环上的位置。 */
.cyclecanvas{position:sticky;top:calc(54px + 18px)}
.cyclecanvas svg{display:block;width:100%;height:auto}
.c-node{cursor:pointer}
.c-node .cb{transition:filter .18s}
.c-node:hover .cb{filter:drop-shadow(0 4px 12px rgba(0,0,0,.5))}

.cyclepanel{display:grid;gap:12px}
.turn{
  background:#16212d;border:1px solid #2a3745;border-left:5px solid var(--blue);
  transition:border-color .2s,background .2s;
}
.turn.corr{border-left-color:var(--orange)}
.turn.sed{border-left-color:var(--yellow)}
.turn.act{background:#1c2937;border-color:#3d5064}
.turn-h{display:flex;align-items:center;gap:13px;padding:14px 17px;cursor:pointer}
.turn-h:hover{background:#1b2836}
.turn-h .no{
  display:grid;place-items:center;width:28px;height:28px;flex:0 0 auto;
  background:#2a3745;color:#c5d0dc;font:800 13.5px/1 var(--mono);
}
.turn.act .turn-h .no{background:var(--blue);color:#fff}
.turn.corr.act .turn-h .no{background:var(--orange)}
.turn.sed.act .turn-h .no{background:var(--yellow)}
.turn-h .lb{font-size:16.5px;font-weight:730;color:#fff}
.turn-h .tool{
  margin-left:auto;padding:4px 10px;background:#20303f;color:#8fbcff;
  font:700 13px/1.5 var(--mono);white-space:nowrap;
}
.turn-h .tool.none{color:#7c8896}
.turn-b{display:none;padding:0 17px 17px}
.turn.open .turn-b{display:block}
.turn-why{
  padding:11px 14px;background:#1f2b38;border-left:4px solid #4a5b6d;
  color:#c3ced9;font-size:14.5px;margin-bottom:12px;
}
.io{display:grid;gap:10px}
.io-box{border:1px solid #2c3946;background:#101a24}
.io-box .h{padding:8px 12px;background:#1a2632;color:#93a1b0;font:800 13px/1.4 var(--mono)}
.io-box pre{
  margin:0;padding:12px;font:500 13px/1.72 var(--mono);color:#dbe4ec;
  white-space:pre-wrap;word-break:break-word;max-height:230px;overflow:auto;
}
.turn-take{margin-top:12px;padding:11px 14px;background:#123055;border-left:4px solid #5aa2ff;color:#cfe0f6;font-size:14.5px}
.turn-take strong{color:#fff}
.gr-jump{
  display:inline-flex;align-items:center;gap:7px;margin-top:11px;padding:7px 13px;
  background:#1462d5;border:0;color:#fff;font:700 13px/1.4 var(--mono);cursor:pointer;
}
.gr-jump:hover{background:#0f4ea8}

/* ---------- 权限边界 ---------- */
.permscene{padding:92px 0 100px;background:var(--white)}
.eyebrow3{margin:0 0 14px;color:var(--orange);font:700 13.5px/1.3 var(--mono)}
.permh2{margin:0;max-width:24em;font-size:clamp(26px,2.7vw,38px);line-height:1.22;font-weight:760}
.permlede{max-width:62em;margin:18px 0 0;color:var(--ink-soft);font-size:clamp(15.5px,1.2vw,18px);line-height:1.7}
.permlede strong{color:var(--ink);font-weight:750}
.permsub{margin:56px 0 6px;font-size:clamp(20px,1.9vw,26px);font-weight:750}
.permlede2{margin:0 0 22px;color:var(--muted);font-size:15.5px}

/* 三类对象 */
.permobjs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin-top:34px}
.pobj{padding:20px 22px;background:#fbfcfd;border:1px solid var(--line);border-top:5px solid var(--green)}
.pobj.warn{border-top-color:var(--orange);background:var(--orange-soft)}
.pobj-k{font:800 13px/1.4 var(--mono);color:var(--muted)}
.pobj-t{margin-top:8px;font-size:18.5px;font-weight:760;line-height:1.32}
.pobj.warn .pobj-t{color:#8a2c06}
.pobj-b{margin:11px 0 0;color:var(--ink-soft);font-size:15px;line-height:1.68}
.pobj-e{
  margin-top:14px;padding:11px 13px;background:#fff;border:1px dashed var(--line);
  color:var(--ink-soft);font-size:14.5px;line-height:1.6;
}

/* 过滤落在哪一步 */
.permwhere{margin-top:30px;padding:24px 26px;background:#f4f7fa;border-left:6px solid var(--blue)}
.pw-lead{margin:0;color:var(--ink-soft);font-size:16px}
.pw-key{
  margin-top:12px;padding:15px 18px;background:#fff;border:2px solid var(--blue);
  color:#0d3f8c;font-size:17px;font-weight:730;line-height:1.6;
}
/* 为什么是"重新生成"而不是"筛选" —— 这段解释的是上面那句话的技术前提 */
.pw-note{
  margin-top:14px;padding:13px 16px;background:#fff;border-left:4px solid var(--line);
  color:var(--ink-soft);font-size:15px;line-height:1.7;
}
.pw-warn{margin-top:14px;color:#8a2c06;font-size:15px;line-height:1.68}

/* 两条路径 */
.permpaths{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.ppath{padding:22px 24px;background:#fbfcfd;border:1px solid var(--line);border-top:5px solid var(--blue)}
.ppath.b{border-top-color:var(--purple)}
.ppath-h{display:flex;align-items:baseline;gap:11px;flex-wrap:wrap}
.ppath-h .tag{padding:4px 10px;background:var(--blue);color:#fff;font:800 13px/1.4 var(--mono)}
.ppath.b .ppath-h .tag{background:var(--purple)}
.ppath-h .nm{font-size:18.5px;font-weight:760}
.ppath-flow{
  display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin-top:16px;
  padding:13px 15px;background:#fff;border:1px solid var(--line-soft);
}
.ppath-flow span{font-size:14px;font-weight:700;color:var(--ink)}
.ppath-flow i{color:var(--muted);font-style:normal;font-size:14px}
.ppath-kv{display:grid;grid-template-columns:52px minmax(0,1fr);gap:0;margin:16px 0 0}
.ppath-kv dt{
  padding:9px 0;font:800 13px/1.5 var(--mono);color:var(--muted);
  border-top:1px solid var(--line-soft);
}
.ppath-kv dd{
  margin:0;padding:9px 0 9px 12px;font-size:14.5px;line-height:1.62;color:var(--ink-soft);
  border-top:1px solid var(--line-soft);
}

/* 待确认问题 */
.permqs{display:grid;gap:11px}
.pq{
  display:flex;align-items:flex-start;gap:14px;padding:16px 20px;
  background:var(--yellow-soft);border-left:5px solid var(--yellow);
}
.pq .no{flex:0 0 auto;font:800 14px/1.5 var(--mono);color:#6b4700}
.pq .tx{font-size:16px;line-height:1.62;color:#6b4700;font-weight:600}

footer{padding:26px 0 44px;background:var(--paper);border-top:1px solid var(--line);color:var(--muted);font-size:13.5px}
footer .wrap{display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap}

/* ---------- modal ---------- */
.mask{position:fixed;inset:0;z-index:100;display:none;background:rgba(12,18,25,.66)}
.mask.on{display:block}
.modal{
  position:fixed;z-index:101;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(920px,calc(100vw - 52px));max-height:calc(100vh - 84px);
  display:none;flex-direction:column;background:var(--white);box-shadow:0 24px 70px rgba(0,0,0,.4);
}
.modal.on{display:flex}
.modal-h{
  flex:0 0 auto;display:flex;align-items:flex-start;justify-content:space-between;gap:18px;
  padding:20px 24px;background:var(--dark);color:#fff;
}
.modal-h .k{margin:0 0 6px;color:#8fbcff;font:800 13px/1.4 var(--mono)}
.modal-h h3{margin:0;font-size:21px;line-height:1.35;font-weight:730}
.modal-h button{flex:0 0 auto;width:34px;height:34px;background:#27333f;border:0;color:#fff;font-size:20px;cursor:pointer}
.modal-h button:hover{background:var(--orange)}
.modal-b{flex:1 1 auto;overflow-y:auto;padding:22px 24px}
.mrow{margin-bottom:20px}
.mrow:last-child{margin-bottom:0}
.mrow .lb{margin-bottom:8px;color:var(--muted);font:800 13px/1.4 var(--mono)}
.mrow .raw{padding:16px;background:#f6f8fa;border:1px solid var(--line);font:500 14.5px/1.85 var(--sans);white-space:pre-wrap}
.kv{display:grid;grid-template-columns:150px minmax(0,1fr);border:1px solid var(--line-soft)}
.kv dt,.kv dd{margin:0;padding:11px 14px;border-bottom:1px solid var(--line-soft);font-size:14.5px}
.kv dt{background:#f4f7f9;color:var(--ink-soft);font:700 13px/1.5 var(--mono)}
.kv dt:last-of-type,.kv dd:last-of-type{border-bottom:0}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  padding:6px 12px;background:var(--blue-soft);border:1.5px solid var(--blue);color:var(--blue);
  font:700 13.5px/1.4 var(--sans);cursor:pointer;
}
.chip:hover{background:var(--blue);color:#fff}
.chip.g{background:var(--green-soft);border-color:var(--green);color:var(--green)}
.chip.g:hover{background:var(--green);color:#fff}
.chip.o{background:var(--orange-soft);border-color:var(--orange);color:var(--orange)}
.chip.o:hover{background:var(--orange);color:#fff}
.chip small{font-family:var(--mono);opacity:.75}
.fragbox{margin-bottom:9px;padding:12px 14px;background:#f9fbfc;border:1px solid var(--line);border-left:6px solid var(--blue)}
.fragbox .s{font:800 13px/1.4 var(--mono)}
.fragbox p{margin:6px 0 0;color:var(--ink-soft);font-size:14.5px}
.warnbox{padding:13px 16px;background:var(--orange-soft);border-left:5px solid var(--orange);color:#8a2c06;font-size:14.5px}
.infobox{padding:13px 16px;background:var(--blue-soft);border-left:5px solid var(--blue);color:#0d3f8c;font-size:14.5px}

/* ---------- narrow / fallback ---------- */
@media (max-width:1080px){
  .cyclebody{grid-template-columns:1fr}
  /* 单列时图在卡片上方，sticky 会让它钉住、卡片从下面穿过 —— 只在双列时才该跟随 */
  .cyclecanvas{position:static}
  .minimap,.taphint{display:none}
  .dagstage{height:auto;overflow:visible}
  .dagcanvas{position:static;top:auto;bottom:auto;padding-top:16px;overflow-x:auto}
  /* 窄屏 viewBox 覆盖整图（约 4378 单位宽，见 app.js fitViewBox），整图靠 .dagcanvas 横向滚动查看。
     CSS 宽度必须 ≥ 4378×0.93 —— 否则 15px 的图内文字渲染出来不足 13px（3400px 时实测 11.65px）。 */
  .dagcanvas svg{width:4100px;height:auto}
  .dagfoot{position:static;height:auto;border-top:0}
  .beat{grid-template-columns:1fr;gap:14px;padding:22px clamp(16px,4vw,28px)}
  .beat-i{flex-direction:row}
  .beat-i em{writing-mode:horizontal-tb}
  /* 权限段：三列/两列都收成一列 */
  .permobjs,.permpaths{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .scrollcue i{animation:none}
}
@media print{
  .rail,.taphint,.minimap,.scrollcue{display:none}
  .dagstage{height:auto;overflow:visible}
  .dagcanvas{position:static}
  .cyclecanvas{position:static}   /* sticky 在分页时会错位 */
  .dagcanvas svg{width:1560px;height:auto}
  .turn-b{display:block !important}
  .mask,.modal{display:none !important}
  .intro,.cyclescene{background:#fff;color:#000}
  .intro .lede,.cyclehead p{color:#333}
}
