/* hub.css —— 总图
 * 低饱和土色分层 + 朱砂点睛。密度靠排版与留白，不靠色彩。
 */

:root{
  color-scheme:only light;
  --paper:#f7f5f0; --card:#fbf9f4;
  --ink:#1c1b19; --ink2:#4a4741; --ink3:#8a857c; --ink4:#b9b3a7;
  --line:#e2ddd2; --line2:#d3ccbd;
  --seal:#a6392e; --seal-soft:rgba(166,57,46,.10);

  /* 四层：低饱和，只有明度与色相差别，不刺眼 */
  --c-cog:#5a6b70;   /* 认知 · 黛青 */
  --c-soc:#8a6a52;   /* 社会 · 赭石 */
  --c-mat:#6b7a5e;   /* 物质 · 苔绿 */
  --c-fnd:#7a7086;   /* 基底 · 灰紫 */

  --serif:"Songti SC","Source Han Serif SC","Noto Serif SC","STSong",Georgia,serif;
  --sans:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",Arial,sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--paper); color:var(--ink);
  font-family:var(--sans); font-size:14px; line-height:1.7;
  -webkit-font-smoothing:antialiased;
}
body::before{
  content:""; position:fixed; inset:0; pointer-events:none; z-index:0;
  background:url("../assets/img/paper.jpg") repeat; background-size:512px 512px;
  mix-blend-mode:multiply; opacity:.38;
}
a{color:inherit}

.wrap{max-width:1180px; margin:0 auto; padding:0 26px; position:relative; z-index:1}

/* ---------------- 顶栏 ---------------- */
.top{
  position:sticky; top:0; z-index:30;
  background:rgba(247,245,240,.94);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.top .wrap{display:flex; align-items:center; gap:18px; height:60px}
.top .back{
  text-decoration:none; color:var(--ink3); font-size:16px;
  padding:4px 6px; border-radius:6px; transition:color .2s var(--ease), background .2s
}
.top .back:hover{color:var(--ink); background:rgba(0,0,0,.04)}
h1{
  font-family:var(--serif); font-size:16px; font-weight:400;
  letter-spacing:.28em; margin:0; white-space:nowrap;
}

/* ---------------- 引导语 ---------------- */
.lede{
  font-family:var(--serif); font-size:14.5px; line-height:2.1;
  color:var(--ink2); margin:30px 0 26px; max-width:64ch;
  letter-spacing:.02em;
}

/* ---------------- PC 泳道图 ---------------- */
.stage{position:relative}
#chart{width:100%; height:auto; display:block; overflow:visible}

/* 层标签 */
.layerlabel{
  font-family:var(--serif); font-size:13px; letter-spacing:.22em;
  fill:var(--ink3);
}
.layerdesc{font-size:10.5px; fill:var(--ink4); letter-spacing:.02em}
.layerrule{stroke:var(--line); stroke-width:1}

/* 模块行 */
.row{transition:opacity .3s var(--ease)}
.modname{
  font-family:var(--serif); font-size:12.5px; fill:var(--ink2);
  cursor:pointer; transition:fill .2s var(--ease);
  letter-spacing:.04em;
}
.modname:hover{fill:var(--seal)}
.modspan{stroke-width:3; stroke-linecap:round; opacity:.20; transition:opacity .3s var(--ease)}
.modspan.on{opacity:.55}
.rowhit{fill:transparent; cursor:pointer}
.builtmark{font-size:9.5px; fill:var(--ink4); letter-spacing:.06em}

/* 因果关系网 */
.edge{
  fill:none; stroke:var(--seal); stroke-width:1;
  opacity:.14; stroke-linecap:round;
  transition:opacity .3s var(--ease), stroke-width .3s var(--ease);
}
.edge.cross{opacity:.34; stroke-width:1.3}
.edge.long{opacity:.12}
.edge.fb{stroke-dasharray:3 3}
.edge.on{opacity:.85 !important; stroke-width:1.8}

/* 空白期注解：把「图上很空」解释掉 */
.gapnote{
  font-size:10px; fill:var(--ink4); letter-spacing:.04em;
  font-family:var(--sans);
}

.node circle{
  fill:var(--paper); stroke:var(--seal); stroke-width:1.5;
  transition:r .25s var(--ease), fill .25s var(--ease), stroke-width .25s;
  cursor:pointer;
}
.node:hover circle{fill:var(--seal); r:7}
.node.dim{opacity:.22}
.node.dim circle{stroke:var(--ink4)}
.node text{
  font-size:10.5px; fill:var(--ink3); letter-spacing:.03em;
  pointer-events:none; transition:opacity .25s var(--ease), fill .25s;
}
.node:hover text{fill:var(--ink)}
.node.sel circle{fill:var(--seal); r:7}
.node.sel text{fill:var(--ink); font-weight:600}

/* 空间不足时隐藏文字，悬停或选中再显示 */
.node.nolabel .nlabel{opacity:0}
.node.nolabel:hover .nlabel,
.node.nolabel.sel .nlabel{opacity:1}
.node.nolabel:hover circle{fill:var(--seal)}

/* 时间轴 */
.axis-line{stroke:var(--line2); stroke-width:1}
.tick{stroke:var(--line2); stroke-width:1}
.tick-label{font-size:10px; fill:var(--ink4); letter-spacing:.02em}
.ticksub{font-size:9px; fill:var(--ink4)}

/* 更早区域 */
.earlyzone{fill:rgba(122,112,134,.05)}
.earlylabel{font-size:10px; fill:var(--ink4); letter-spacing:.12em}
.breakmark{stroke:var(--ink4); stroke-width:1; stroke-dasharray:2 3}

/* ---------------- 详情面板 ---------------- */
.panel-wrap{position:fixed; inset:0; z-index:60}
.panel-wrap[hidden]{display:none}
.backdrop{
  position:absolute; inset:0; background:rgba(40,34,28,.22);
  opacity:0; transition:opacity .3s var(--ease);
}
.panel-wrap.open .backdrop{opacity:1}
.panel{
  position:absolute; top:0; right:0; bottom:0; width:min(440px,92vw);
  background:var(--card); border-left:1px solid var(--line);
  box-shadow:-14px 0 44px rgba(60,50,35,.13);
  padding:34px 30px 44px; overflow-y:auto; overscroll-behavior:contain;
  transform:translateX(100%); transition:transform .34s var(--ease);
}
.panel-wrap.open .panel{transform:translateX(0)}
.pclose{
  position:absolute; top:16px; right:18px; border:0; background:transparent;
  color:var(--ink4); font-size:15px; cursor:pointer; padding:6px;
  transition:color .2s
}
.pclose:hover{color:var(--ink)}

.pname{font-family:var(--serif); font-size:23px; letter-spacing:.06em; margin:0 0 6px}
.pmeta{font-size:12px; color:var(--ink4); letter-spacing:.1em; margin-bottom:20px}
.pmod{
  display:inline-block; font-size:11.5px; padding:2px 10px; border-radius:6px;
  background:rgba(0,0,0,.045); color:var(--ink2); margin-right:6px;
}
.psec{margin:22px 0 0}
.psec h4{
  font-family:var(--serif); font-size:12px; font-weight:400;
  letter-spacing:.2em; color:var(--ink3); margin:0 0 8px;
  padding-bottom:7px; border-bottom:1px solid var(--line);
}
.psec p{margin:0; font-size:13.5px; line-height:1.95; color:var(--ink2)}
.psrc{font-size:12px; line-height:1.85; color:var(--ink3)}
.pnote{
  margin-top:10px; padding:10px 13px; border-radius:8px;
  background:rgba(166,57,46,.05); border-left:2px solid var(--seal);
  font-size:12.5px; line-height:1.85; color:var(--ink2);
}
.pleavelink{
  display:inline-flex; align-items:center; gap:6px; margin-top:22px;
  font-size:13px; color:var(--seal); text-decoration:none;
  border-bottom:1px solid var(--seal-soft); padding-bottom:2px;
}
.pleavelink:hover{border-color:var(--seal)}

.ev{font-size:10px; vertical-align:middle}
.ev.solid{color:#3f7a5a}
.ev.debated{color:#a8842e}
.ev.speculative{color:#a6392e}

/* ---------------- 手机：脊椎叙事 ---------------- */
.mstage{display:none}

.mlay{
  margin:0 0 34px;
}
.mlayhd{
  display:flex; align-items:baseline; gap:10px;
  padding-bottom:9px; border-bottom:1px solid var(--line); margin-bottom:14px;
}
.mlaymk{
  font-family:var(--serif); font-size:13px; letter-spacing:.1em;
  width:22px; height:22px; display:flex; align-items:center; justify-content:center;
  border-radius:5px; color:#fff; flex:none;
}
.mlaymk.cognition{background:var(--c-cog)}
.mlaymk.society{background:var(--c-soc)}
.mlaymk.material{background:var(--c-mat)}
.mlaymk.foundation{background:var(--c-fnd)}
.mlaynm{font-family:var(--serif); font-size:14px; letter-spacing:.16em}
.mlayds{font-size:11.5px; color:var(--ink4)}

.mmod{
  display:block; text-decoration:none; padding:13px 2px;
  border-bottom:1px solid var(--line);
  transition:background .2s var(--ease), padding-left .2s var(--ease);
}
.mmod:active{background:rgba(0,0,0,.03)}
.mmod .mn{
  font-family:var(--serif); font-size:15px; letter-spacing:.05em;
  display:flex; align-items:center; gap:8px;
}
.mmod .mtag{
  font-family:var(--sans); font-size:10px; letter-spacing:.08em;
  color:var(--ink4); border:1px solid var(--line2); border-radius:4px;
  padding:0 5px;
}
.mmod .mo{font-size:12.5px; color:var(--ink3); margin-top:3px}
.mmod .msp{font-size:11px; color:var(--ink4); margin-top:4px; font-variant-numeric:tabular-nums}

/* 手机脊椎 */
.mspinehd{
  font-family:var(--serif); font-size:14px; letter-spacing:.18em;
  color:var(--ink2); margin:6px 0 4px;
}
.mspineds{font-size:12.5px; color:var(--ink4); margin:0 0 16px; line-height:1.8}

details.mnode{
  border-bottom:1px solid var(--line);
}
details.mnode summary{
  list-style:none; cursor:pointer; padding:14px 2px;
  display:flex; align-items:flex-start; gap:11px;
}
details.mnode summary::-webkit-details-marker{display:none}
.mdot{
  width:7px; height:7px; border-radius:50%; border:1.5px solid var(--seal);
  margin-top:7px; flex:none; background:var(--paper);
  transition:background .2s
}
details.mnode[open] .mdot{background:var(--seal)}
.mnode-main{flex:1; min-width:0}
.mnode-nm{font-family:var(--serif); font-size:15px; letter-spacing:.05em}
.mnode-tm{font-size:11px; color:var(--ink4); margin-left:8px; font-variant-numeric:tabular-nums}
.mnode-broke{font-size:12.5px; color:var(--ink2); margin-top:4px}
.mnode-rel{font-size:12.5px; color:var(--seal); margin-top:2px}
.mnode-body{padding:0 2px 18px 18px; font-size:12.5px; line-height:1.9; color:var(--ink3)}
.mnode-body .src{margin-top:8px; color:var(--ink3)}
.mnode-body .note{
  margin-top:10px; padding:10px 13px; border-radius:8px;
  background:rgba(166,57,46,.05); border-left:2px solid var(--seal); color:var(--ink2);
}

.foot{
  font-size:12px; color:var(--ink4); line-height:1.9;
  margin:44px 0 60px; padding-top:18px; border-top:1px solid var(--line);
  letter-spacing:.02em;
}

/* ---------------- 响应式 ---------------- */
@media (max-width:860px){
  .wrap{padding:0 20px}
  .top .wrap{height:54px; gap:12px}
  h1{font-size:14px; letter-spacing:.2em}
  .lede{font-size:13.5px; line-height:2; margin:22px 0 20px}

  .stage{display:none}
  .mstage{display:block}

  .panel{
    top:auto; left:0; right:0; bottom:0; width:auto;
    max-height:82vh; border-left:0; border-top:1px solid var(--line);
    border-radius:16px 16px 0 0;
    padding:26px 22px calc(30px + env(safe-area-inset-bottom));
    transform:translateY(100%);
  }
  .panel-wrap.open .panel{transform:translateY(0)}
  .pclose{top:12px; right:14px}
  .pname{font-size:20px}
}

@media (prefers-reduced-motion:reduce){
  *{transition-duration:.01ms !important; animation-duration:.01ms !important}
}
