/*
Theme Name: 飞鸿品农
Theme URI: https://jianzhuxue.net/
Author: 飞鸿品农
Author URI: https://jianzhuxue.net/
Description: 飞鸿品农内容中枢。首页是落地页；内容页把「农产品流通细分研究」与「农产品流通地图」放在底部切换，地图带右侧图层面板、可缩放、右上角渐显经纬网，点开点位进文章浮窗（含评论）。层级与文章全部实时读取 WordPress 后台分类。配色按《飞鸿品农网页色彩标准》执行，含夜间模式。数据按页面按需加载，图表库与底图只在内容页挂。
Version: 2.1.0
Requires at least: 6.0
Tested up to: 6.8
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: feihong-pinnong
*/

/* ============================================================
   一、设计令牌
   亮色是默认；夜间只覆盖同名令牌的值，用法与令牌名不变。
   色值全部登记在 脚本/色彩标准/色板.json，改色改那里。
   ============================================================ */
:root{
  --paper:#f7f6f3;
  --paper-up:#fcfbf7;
  --surface:#ffffff;
  --surface-2:#faf9f6;
  --plate:#faf9f6;          /* 图版托盘：图表封面、二维码（浅色位图不随主题换底） */

  --ink:#151a17;
  --ink2:#4a4f4a;
  --muted:#6f6c64;     /* D1：WCAG AA 正文要求 ≥4.5:1。原 #8f8c83 在 --paper(#f7f6f3) 上只有
                          3.11:1，全站 25 处次级文字（导语、日期、页脚、图注…）都不达标。
                          这个值在 #f7f6f3 上 4.85:1、在 #fff 上 5.24:1。夜间不动（5.18:1 已合格）。 */
  --muted-ink:#6f6c64;

  --line:#e7e4db;
  --line2:#d9d5c9;

  --accent:#17463a;
  --accent2:#b0812c;
  --accent2-ink:#8a621f;
  --on-accent:#ffffff;

  /* 六类别分类色，按索引用（--s0 ~ --s5） */
  --s0:#1d5c46; --s1:#b0812c; --s2:#486581;
  --s3:#7a4a63; --s4:#b3543a; --s5:#4a4f4a;

  /* 地图 */
  --mv-base:#d5ddb9;
  --mv-inset:#cfd9b4;
  --mv-hover:#2f5a3e;
  --mv-hover-label:#ffffff;
  --mv-jd:#5f7259;
  --mv-label:#3b4a31;
  --mv-grid:#b9b3a2;
  --mv-mark-base:#2f5a3e;
  --mv-mark-mkt:#96691f;
  --mv-mark-ent:#b3543a;
  --mv-mark-ring:#ffffff;
  --mv-inset-line:#cfcabd;

  --ok:#2f6b4f;
  --warn:#8f6620;
  --err:#a8402f;
  --info:#486581;
  --chart-fallback:#7b8a5f;

  /* 阴影底色（rgba 用），亮色是深墨、夜间是纯黑 */
  --shade:21,26,23;

  --serif:"Songti SC","STSong","Noto Serif SC","SimSun",serif;
  --topH:66px;
  --footH:36px;
  --dockH:81px;
  --ease:cubic-bezier(.22,1,.36,1);
}

:root[data-theme="dark"]{
  --paper:#1b1a16;
  --paper-up:#232119;
  --surface:#231f19;
  --surface-2:#2a261e;
  --plate:#f5f2ea;

  --ink:#f1eee6;
  --ink2:#cac5b9;
  --muted:#918d83;
  --muted-ink:#a9a499;

  --line:#322e26;
  --line2:#443f34;

  --accent:#86b39a;
  --accent2:#d6a94f;
  --accent2-ink:#dcb265;
  --on-accent:#12211a;

  --s0:#6fae8d; --s1:#d6a94f; --s2:#8fb0cc;
  --s3:#c58aa9; --s4:#d98a72; --s5:#b3aea2;

  --mv-base:#39432f;
  --mv-inset:#333d2b;
  --mv-hover:#8fae7a;
  --mv-hover-label:#1b1a16;
  --mv-jd:#8a9a80;
  --mv-label:#d2d7c1;
  --mv-grid:#4d5642;
  --mv-mark-base:#8fc7a4;
  --mv-mark-mkt:#e2b667;
  --mv-mark-ent:#dc8f70;
  --mv-mark-ring:#1b1a16;
  --mv-inset-line:#443f34;

  --ok:#79bf9a;
  --warn:#e0b463;
  --err:#e08a76;
  --info:#93b8d6;
  --chart-fallback:#9aab7e;

  --shade:0,0,0;
}

*{box-sizing:border-box;margin:0;padding:0}
/* P0-2（2026-10-06）：解锁视口，回归文档流。
   原来 html,body{height:100%} + #stage{position:fixed;overflow-y:auto} 把整页钉死在
   一屏里，浏览器永远不滚（window.scrollY 恒为 0）：手机地址栏不收缩、锚点跳转失效、
   Ctrl+F 页内查找定位错乱、桌面滚动条缩在内容区右缘（「套壳感」的第一来源）。
   现在只留一个滚动容器 —— 文档本身。 */
html{min-height:100%;scroll-padding-top:calc(var(--topH) + 14px)}
body{
  min-height:100vh;
  min-height:100dvh;
  font:14px/1.65 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  background:var(--paper);color:var(--ink);
  -webkit-font-smoothing:antialiased;
  transition:background .3s ease,color .3s ease;
}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}
img{max-width:100%}
[hidden]{display:none!important}
::selection{background:color-mix(in srgb,var(--accent) 22%,transparent)}

/* 滚动条：夜间也跟着走 */
*{scrollbar-color:var(--line2) transparent;scrollbar-width:thin}
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:var(--line2);border-radius:9px;border:3px solid transparent;background-clip:content-box}
*::-webkit-scrollbar-track{background:transparent}

/* 分类色：节点只带一个索引，具体色值分主题给，夜间自动换成另一组 */
[data-ci="0"]{--c:var(--s0)}
[data-ci="1"]{--c:var(--s1)}
[data-ci="2"]{--c:var(--s2)}
[data-ci="3"]{--c:var(--s3)}
[data-ci="4"]{--c:var(--s4)}
[data-ci="5"]{--c:var(--s5)}

/* ============================================================
   二、外框流动：每块卡片描一圈会缓慢流动的渐变边
   实现是 @property 角度 + 圆锥渐变 + xor 遮罩只留 1px 边。
   列表里的卡片默认静止（几十张同时跑会掉帧），指上去才动；
   结构块（首页入口、地图画框、层级目录、浮窗）常驻流动。
   ============================================================ */
@property --fhn-flow{syntax:"<angle>";inherits:false;initial-value:0deg}
@keyframes fhnFlow{to{--fhn-flow:360deg}}

.flow{position:relative}
.flow::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  padding:1px;
  background:conic-gradient(from var(--fhn-flow),
    transparent 0deg 34deg,
    color-mix(in srgb,var(--c,var(--accent)) 82%,transparent) 82deg,
    color-mix(in srgb,var(--accent2) 92%,transparent) 118deg,
    transparent 160deg 312deg,
    color-mix(in srgb,var(--c,var(--accent)) 46%,transparent) 352deg,
    transparent 360deg);
  /* 遮罩只看 alpha，颜色本身不显示；用 --ink 而不是纯黑，色板里就不必塞一个黑色条目 */
  -webkit-mask:linear-gradient(var(--ink) 0 0) content-box,linear-gradient(var(--ink) 0 0);
  mask:linear-gradient(var(--ink) 0 0) content-box,linear-gradient(var(--ink) 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:.42;transition:opacity .34s ease;
  animation:fhnFlow 7.5s linear infinite;animation-play-state:paused;
}
.flow:hover::after,.flow.on::after{opacity:1;animation-play-state:running}
.flow-live::after{animation-play-state:running}
.flow-live::after{opacity:.6}
.flow-live:hover::after{opacity:1}
@media (prefers-reduced-motion:reduce){
  .flow::after{animation:none!important;opacity:.5}
  /* 平移缩放类动效一律关掉，只留透明度过渡 */
  #stage{transition:none!important}
  #stage.reading #cards > *{animation:none!important}
  #post.panel .box{animation:fade .2s ease both!important}
  .card:active,.row:active,.mask .x:hover{transform:none!important}
}

/* ============================================================
   三、顶栏
   ============================================================ */
#topbar{
  /* P0-2：fixed → sticky。整页改回文档流之后，顶栏自己钉在视口顶，
     不再靠「内容区从 topH 开始」来假装。 */
  position:sticky;top:0;height:var(--topH);z-index:40;
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:clamp(12px,2.4vw,28px);padding:0 clamp(14px,2.8vw,34px);
  background:color-mix(in srgb,var(--paper) 86%,transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
#brand{display:inline-flex;align-items:center;gap:10px;font-weight:600;letter-spacing:.02em}
/* 品牌标两张：亮色一张、夜间一张。
   规则要在同一个特异性档上按顺序生效：先 .mk{display:block}，再用 .mk-d 关掉夜间那张。
   写成 `#brand .mk{display:block}` 会让 #brand 里那张夜间标关不掉（id 选择器压过类），
   而浮层里两张会同时显示 —— 两个坑都踩过。 */
.mk{display:block;height:auto}
.mk-d{display:none}
:root[data-theme="dark"] .mk-l{display:none}
:root[data-theme="dark"] .mk-d{display:block}
#brand .mk{height:34px;width:auto}
#follow .fHead .mk{height:44px;width:auto}
#brand span{font-size:16.5px;white-space:nowrap}

#qWrap{position:relative;width:100%;max-width:566px;justify-self:center}
#q{
  width:100%;height:44px;border-radius:999px;border:1px solid var(--line2);
  background:var(--surface);padding:0 44px 0 20px;font-size:14px;color:var(--ink);
  outline:none;transition:border-color .2s,box-shadow .2s,background .3s;
}
#q::placeholder{color:var(--muted)}
#q:focus{border-color:color-mix(in srgb,var(--accent) 42%,var(--line2));
  box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 10%,transparent)}
#qClear{
  position:absolute;right:8px;top:50%;transform:translateY(-50%);
  width:28px;height:28px;border-radius:50%;color:var(--muted);font-size:15px;
  display:grid;place-items:center;
}
#qClear:hover{background:var(--line);color:var(--ink)}
/* P1-2：手机档的搜索开关与地图全屏开关。桌面档不出现 ——
   桌面顶栏本来就是单行、搜索框一直可见，再放个开关是多余的。 */
#qTog{display:none;width:38px;height:38px;border-radius:10px;color:var(--ink2);
  border:1px solid var(--line);align-items:center;justify-content:center}
#qTog:hover{border-color:var(--accent);color:var(--accent)}
#qTog svg{width:17px;height:17px}
body.qOpen #qTog{border-color:var(--accent);color:var(--accent)}
/* P1-2 连带项：手机档「关于我」的顶栏入口。桌面档页脚里本来就有按钮，这里关掉。 */
#aboutTog{display:none;width:38px;height:38px;border-radius:10px;color:var(--ink2);
  border:1px solid var(--line);align-items:center;justify-content:center}
#aboutTog:hover{border-color:var(--accent);color:var(--accent)}
#aboutTog svg{width:17px;height:17px}
#mvFull{display:none}
#mvFull .i-shink{display:none}
body.mvFull #mvFull .i-expand{display:none}
body.mvFull #mvFull .i-shink{display:block}
/* P1-4：地图提示文案按输入设备切换。
   触屏上没有「滚轮」，写「滚轮缩放」等于给读者一句用不上的说明。 */
.mvHint .hTouch{display:none}
@media (hover:none),(pointer:coarse),(max-width:760px){
  .mvHint .hDesk{display:none}
  .mvHint .hTouch{display:inline}
}
/* 只留一个叉：type=search 在 WebKit 里自带一个原生清除按钮，
   会叠在自己那个 #qClear 上 —— 表现就是「输入框里有两个叉」。 */
#q::-webkit-search-cancel-button,
#q::-webkit-search-decoration,
#q::-webkit-search-results-button,
#q::-webkit-search-results-decoration{-webkit-appearance:none;appearance:none;display:none}

#auth{display:flex;gap:9px;align-items:center}
#auth .btn{
  /* 这一条原本只写尺寸与配色 —— 文字能居中全靠 <button> 的浏览器默认样式。
     后来「登录 / 注册」由 <button> 换成了 <a>（要跳转），<a> 没有那套默认行为，
     文字就顶到上沿（实测距顶 3px、距底 15px，看着就是「字歪了」）。
     自己显式居中，别再依赖标签类型。 */
  display:inline-flex;align-items:center;justify-content:center;
  height:34px;padding:0 16px;border-radius:999px;font-size:13px;
  border:1px solid var(--line2);background:var(--surface);color:var(--ink2);
  transition:border-color .2s,color .2s,background .3s;
}
#auth .btn:hover{border-color:var(--accent);color:var(--accent)}
#auth .btn.solid{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
#auth .btn.solid:hover{filter:brightness(1.08)}
#auth .btn.icon{width:34px;padding:0;display:grid;place-items:center}
#auth .btn.icon svg{width:17px;height:17px}
#auth .btn.icon .i-moon{display:none}
:root[data-theme="dark"] #auth .btn.icon .i-sun{display:none}
:root[data-theme="dark"] #auth .btn.icon .i-moon{display:block}

/* ============================================================
   四、舞台
   ============================================================ */
#stage{
  /* P0-2：fixed + overflow-y:auto → 普通文档流。
     整页锁视口的最后一块拼图就是它。现在页面自己滚，顶栏 sticky 钉住，
     底部 dock / 版权行仍是 fixed，用 padding-bottom 让开它们的高度
     （--stageBottom 由 site.js 的 syncDock() 实测写入）。 */
  position:relative;z-index:1;
  overflow-x:clip;            /* 用 clip 不用 hidden：hidden 会顺带把 overflow-y 算成 auto，
                                 等于又造了一个内滚容器，前功尽弃 */
  padding:clamp(20px,3.2vh,46px) clamp(16px,3.2vw,44px) 46px;
  padding-bottom:calc(var(--stageBottom,36px) + 46px);
  display:flex;flex-direction:column;
  transition:margin-right .42s var(--ease);
}
#viewTree,#viewMap,#home{flex:1 0 auto;max-width:1180px;width:100%;margin:0 auto}

/* ============================================================
   四之二、阅读态：打开文章时，列表缩到侧边，文章在右侧展开
   ------------------------------------------------------------
   原来是居中弹窗，把整页盖住、读完还得关掉再看下一篇。
   现在改成主从两栏：舞台向右让出 --readW，列表自然挤成窄侧栏，
   文章在右侧铺开；侧栏仍然可点，点另一条就直接换文章。
   舞台宽度是连续变化的（right 有过渡），卡片栅格会跟着一路重排，
   「缩小」这件事由布局本身完成，不靠 transform 硬缩。
   地图页没有标题列表可缩，不走这一支（JS 里按 .view === 'tree' 判）。
   ============================================================ */
:root{--readW:min(820px,56vw);--stageBottom:36px}

#stage.reading{margin-right:var(--readW)}
#stage.reading #viewTree{max-width:none}

/* 侧栏态：头部让位、列表压单列、字号与内边距一起收 */
#stage.reading #head{margin-bottom:16px}
#stage.reading #eyebrow{font-size:12px;letter-spacing:.2em;margin-bottom:7px}
#stage.reading #title{font-size:clamp(19px,1.42vw,23px)}
#stage.reading #desc{
  font-size:12.5px;margin-top:8px;line-height:1.7;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
#stage.reading #stats{gap:5px 15px;margin-top:10px;font-size:12px}
#stage.reading #stats b{font-size:13px}

#stage.reading #cards{grid-template-columns:1fr;gap:7px}
#stage.reading .card{border-radius:11px;box-shadow:inset 2px 0 0 var(--c,var(--accent))}
#stage.reading .card:hover{transform:translateY(-1px)}
#stage.reading .card::before{display:none}
#stage.reading .card .cov{display:none}
#stage.reading .card .bd{padding:11px 13px;gap:5px;transition:padding .34s var(--ease)}
#stage.reading .card .no{font-size:12px;letter-spacing:.12em}
#stage.reading .card .nm{font-size:13.5px;line-height:1.5;transition:font-size .34s var(--ease)}
#stage.reading .card .ds{display:none}
#stage.reading .card .ft{font-size:12px;gap:11px}
#stage.reading .card .ft .go{display:none}

#stage.reading .row{padding:10px 13px;margin-bottom:6px;gap:11px}
#stage.reading .row .rn{width:30px;font-size:12px}
#stage.reading .row .rt{font-size:13px}
#stage.reading .row .ra{display:none}

/* 进侧栏时列表整体从左侧平移归位一下，避免「啪」地跳一下。
   错峰靠 --i，由 JS 在进入阅读态时按序写上。 */
#stage.reading #cards > *{
  animation:fhnSlide .46s var(--ease) both;
  animation-delay:calc(var(--i,0) * 22ms);
}
@keyframes fhnSlide{
  from{opacity:.5;transform:translateX(-16px) scale(.965)}
  to{opacity:1;transform:none}
}

/* ---------------- 文章面板：从右侧展开 ---------------- */
#post.panel{
  top:var(--topH);bottom:var(--stageBottom);
  padding:0;place-items:stretch;justify-items:end;
  background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
  pointer-events:none;                 /* 托盘不吃点击，侧栏仍然可点 */
  animation:none;
}
#post.panel .box{
  width:var(--readW);max-width:none;max-height:none;height:100%;
  border-width:0 0 0 1px;border-radius:0;
  box-shadow:-30px 0 70px -46px rgba(var(--shade),.95);
  animation:paneIn .5s var(--ease) both;pointer-events:auto;
}
/* 这一态下面板是**满高**的，那圈流光会贴着整条侧边转一整圈 —— 又长又吵，
   而这时候读者在看正文，边框不该抢戏。只在这一态去掉；
   居中弹窗（地图页点开的那种）保留，那里它是个合适的「这是个弹层」的信号。 */
#post.panel .box::after{display:none}
#post.panel .box .x{
  /* 文章很长，滚到中段也要点得到关闭。
     注意别用 position:fixed —— .box 上挂着入场动画（transform），
     会把它变成 fixed 的包含块，fixed 退化成跟着内容一起滚。
     用 sticky：钉在滚动容器顶上，-44px 负下边距让它不占版面。 */
  position:sticky;top:8px;right:auto;z-index:5;
  width:36px;height:36px;margin:0 14px -44px auto;
  background:color-mix(in srgb,var(--surface) 92%,transparent);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
@keyframes paneIn{
  from{opacity:0;transform:translateX(34px) scale(.984)}
  to{opacity:1;transform:none}
}

/* 窄屏：两栏排不下，面板改成整屏阅读页（从下往上推上来） */
@media (max-width:959px){
  #stage.reading{margin-right:0}
  #post.panel{
    background:var(--surface);pointer-events:auto;animation:fade .2s ease both;
  }
  #post.panel .box{
    width:100%;height:100%;border:0;border-radius:0;box-shadow:none;
    animation:paneUp .42s var(--ease) both;
  }
  /* 关闭按钮在窄屏上放大一点，手指好点 */
  #post.panel .box .x{width:38px;height:38px;margin:0 12px -46px auto}
}
@keyframes paneUp{from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:none}}

#head{margin-bottom:clamp(20px,3.2vh,40px)}
#eyebrow{
  font-size:12px;letter-spacing:.28em;color:var(--muted);
  text-transform:uppercase;margin-bottom:12px;min-height:1em;
}
#title{
  font-family:var(--serif);font-weight:600;letter-spacing:.01em;
  font-size:clamp(27px,3.1vw,40px);line-height:1.3;
}
#desc{margin-top:12px;color:var(--ink2);font-size:14.5px;max-width:66ch}
#stats{display:flex;flex-wrap:wrap;gap:9px 22px;margin-top:16px;color:var(--muted);font-size:13px}
/* 大类分类页页头的状态标记（十六个大类各挂一个，见 index.php）。
   .st / .st-live / .st-updating / .st-building 与首页十六大类目录共用同一套。 */
.majorState{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px}
.majorNote{font-size:12.5px;color:var(--muted)}
#feed .emptyBox a{color:var(--accent);font-size:13.5px}
#feed .emptyBox a:hover{text-decoration:underline}
#stats b{color:var(--ink);font-weight:600;font-size:15px;margin-right:3px;font-variant-numeric:tabular-nums}

/* ============================================================
   五、卡片 / 文章行 / 空态
   ============================================================ */
#cards{display:grid;gap:clamp(13px,1.4vw,19px);align-items:stretch}
/* P1-6（2026-10-06）：类别层就六张卡，原来一列 272px。
   1440 视口下内容宽 1180px → floor(1199/291)=4 列，六张排成 4+2，第二行右边空两格。
   抬到 320px，同一宽度恰好落 3 列，六张自然铺满两行（3+3）；平板落 2 列也齐。 */
#cards.g1{grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}
#cards.g2{grid-template-columns:repeat(auto-fill,minmax(244px,1fr))}
#cards.g3{grid-template-columns:repeat(auto-fill,minmax(258px,1fr))}
#cards.g4{grid-template-columns:1fr}

.card{
  position:relative;text-align:left;overflow:hidden;height:100%;
  background:var(--paper);border:1px solid var(--line);border-radius:15px;
  box-shadow:inset 3px 0 0 var(--c,var(--accent));
  transition:transform .34s var(--ease),border-color .24s,box-shadow .34s,background .3s;
  animation:pop .58s var(--ease) both;
}
.card:hover{
  transform:translateY(-3px);border-color:transparent;
  box-shadow:inset 3px 0 0 var(--c,var(--accent)),0 18px 44px -30px rgba(var(--shade),.5);
}
.card::before{
  content:"";position:absolute;inset:0;opacity:0;transition:opacity .3s;pointer-events:none;
  background:radial-gradient(230px circle at var(--mx,50%) var(--my,50%),
    color-mix(in srgb,var(--c,var(--accent)) 10%,transparent),transparent 70%);
}
.card:hover::before{opacity:1}
.card .bd{padding:20px 22px;display:flex;flex-direction:column;gap:10px;height:100%}
.card .no{
  font-size:12px;letter-spacing:.16em;color:var(--c,var(--accent));
  font-weight:600;font-variant-numeric:tabular-nums;
}
.card .nm{font-family:var(--serif);font-size:18px;font-weight:600;line-height:1.5;pointer-events:none}
.card .ds{font-size:12.5px;color:var(--muted);line-height:1.75}
.card .ft{
  margin-top:auto;display:flex;align-items:center;gap:14px;
  font-size:12px;color:var(--muted);
}
.card .ft b{color:var(--ink2);font-weight:600;font-variant-numeric:tabular-nums}
.card .ft .go{margin-left:auto;color:var(--c,var(--accent));font-size:15px}
.card .ft .wait{color:var(--muted);font-style:normal;letter-spacing:.06em}
.card .cov{
  height:170px;display:grid;place-items:center;padding:14px 16px;
  background:var(--plate);
  border-bottom:1px solid var(--line);
}
.card .cov img{max-width:100%;max-height:100%;object-fit:contain;display:block}

.row{
  position:relative;display:flex;align-items:baseline;gap:14px;width:100%;text-align:left;
  padding:13px 18px;border:1px solid var(--line);border-radius:12px;
  background:var(--paper);margin-bottom:8px;
  transition:border-color .2s,transform .3s var(--ease),background .3s;
  animation:pop .5s var(--ease) both;
}
.row:hover{border-color:var(--line2);transform:translateX(4px)}
.row .rn{
  flex:none;width:44px;font-size:12px;color:var(--c,var(--accent));
  font-variant-numeric:tabular-nums;letter-spacing:.05em;
}
.row .rt{flex:1;font-size:14.5px;line-height:1.6}
.row .ra{flex:none;color:var(--muted);font-size:13px}

.emptyBox{
  position:relative;border:1px dashed var(--line2);border-radius:15px;background:var(--paper);
  padding:44px 30px;text-align:center;color:var(--muted);
  animation:pop .5s var(--ease) both;
}
.emptyBox b{display:block;font-size:15.5px;color:var(--ink2);font-weight:600;margin-bottom:8px}
.emptyBox p{font-size:13px;line-height:1.8}

@keyframes pop{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}

/* 卡片与文章行入场多带一点缩放，点进去/退回来时层次感更明显。
   与 pop 的区别只在多了一个 scale(.975)，动画时长与错峰沿用原来的。 */
@keyframes fhnRise{from{opacity:0;transform:translateY(18px) scale(.975)}to{opacity:1;transform:none}}
.card{animation:fhnRise .58s var(--ease) both}
.row{animation:fhnRise .5s var(--ease) both}
/* 按下时缩一下，松开弹回 */
.card:active{transform:translateY(-1px) scale(.985)}
.row:active{transform:translateX(2px) scale(.995)}

/* ============================================================
   六、落地首页
   ============================================================ */
/* P1-1：区块间距按视口高走 5.6vh → 3.2vh。1440×900 下每处省 9px、
   三处省 27px，配合类别速览改目录式，一起把「最新发布」抬进首屏。 */
#home{display:flex;flex-direction:column;gap:clamp(24px,3.2vh,44px)}
/* 品牌在左、定位句在右，两栏底对齐。
   原来是竖着摞的：标题只占左边一块，右边整片空着，整页看着往左歪。
   align-items:end 让两栏**底边齐**，比顶齐更像「并排的两块」。 */
.hmHero{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(22px,4vw,64px);align-items:end;
}
.hmHeroL{min-width:0}
.hmHeroR{min-width:0}
.hmHero .eb{
  font-size:12px;letter-spacing:.28em;color:var(--muted);
  text-transform:uppercase;margin-bottom:10px;
}
.hmHero h1{
  font-family:var(--serif);font-weight:600;line-height:1.2;
  font-size:clamp(30px,4.2vw,52px);letter-spacing:.01em;
}
/* 定位句是**配角**：站名才是主角。
   原来 18px、用 --ink2（#4a4f4a，深灰），跟站名抢注意力 —— 用户原话「太喧宾夺主」。
   现在 16px（窄屏收到 15px）+ --muted（#8f8c83），与站名上面那行小字同一档灰；
   对纸底的对比度 7.75 → 3.11，正好落到「读得清但不抢」那一段
   （站里的判据是 ≥3，跟眉标、图注一档）。
   字号小了量也得跟着放宽到 44em → 48em，右边缘仍够到容器内侧：
   留白 310px(26%) → 120px(10%) → 现在 144px(12%)。
   ⚠️ 斜率跟容器封顶宽度对齐：#home 封顶 1180px，视口过 1200 后容器不再长，
   1.35vw 到 1185px 就顶到 16px —— 用 1.25vw 的话 1280 屏会掉到 16 以下、
   右边又空出来。 */
.hmHero .lead{
  margin:0;color:var(--muted);line-height:1.8;max-width:40em;
  font-size:clamp(14px,1.2vw,15px);
  /* P1-1：主张句压到两行 —— 它是配角，负责「说清这个站是干什么的」，
     不必把 68 个字一行不落地铺满右半边。想只留一句，
     改后台「飞鸿品农 → 首页定位句」即可，模板不写死文案。 */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

/* 主张区的那组数字：衬线特大号，下配 11px 注。
   数字是这个站最硬的资产，该占最显眼的位置。 */
.hmNums{display:flex;flex-wrap:wrap;gap:clamp(18px,3vw,44px);margin-top:clamp(14px,2.2vh,22px)}
.hmNums b{
  display:block;font-family:var(--serif);font-weight:600;line-height:1;
  font-size:clamp(26px,2.8vw,34px);font-variant-numeric:tabular-nums;
}
.hmNums i{display:block;margin-top:6px;font-style:normal;font-size:12px;
  letter-spacing:.06em;color:var(--muted)}

/* 竖排屏放不下两栏：退回上下堆，定位句跟标题左对齐 */
@media (max-width:860px){
  .hmHero{grid-template-columns:1fr;gap:0}
  .hmHeroR{margin-top:14px}
  .hmHero .lead{margin:0;max-width:46em}
}

.hmEntry{display:grid;gap:clamp(14px,1.8vw,22px);grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.hmCard{
  position:relative;display:flex;flex-direction:column;gap:8px;overflow:hidden;
  background:var(--paper);border:1px solid var(--line);border-radius:16px;
  padding:20px 22px 16px;   /* P1-1：26/22 → 20/16，两张卡省 12px */
  transition:transform .34s var(--ease),border-color .24s,box-shadow .34s,background .3s;
  animation:pop .6s var(--ease) both;
}
.hmCard:hover{transform:translateY(-3px);border-color:transparent;
  box-shadow:0 20px 48px -34px rgba(var(--shade),.55)}
/* 鼠标跟随的底光。子页面的卡片一直有这套（见 .card::before），首页的块之前
   只有边框在转、底面是死的 —— 指上去两种页面的手感不一样。同一套观感。 */
.hmCard::before,.hmChip::before{
  content:"";position:absolute;inset:0;opacity:0;transition:opacity .3s;pointer-events:none;
  background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),
    color-mix(in srgb,var(--c,var(--accent)) 10%,transparent),transparent 70%);
}
.hmCard:hover::before,.hmChip:hover::before{opacity:1}
.hmCard .glyph{
  width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  background:color-mix(in srgb,var(--accent) 7%,var(--paper));
  border:1px solid var(--line);color:var(--accent);margin-bottom:2px;
}
.hmCard .glyph svg{width:20px;height:20px;opacity:.78}
.hmCard b{font-family:var(--serif);font-size:18px;font-weight:600;line-height:1.4}
.hmCard p{font-size:13px;color:var(--muted);line-height:1.75;margin:0}
/* 「进去看 / 去看地图」一律贴卡片底（margin-top:auto 把剩余空间吃掉）。
   两张卡并排时链接底距一致 —— 原来左卡链接吊在半空、底下空一块，
   右边那张却贴底，并排看就是齐不了。 */
.hmCard .go{margin-top:auto;padding-top:8px;font-size:13px;color:var(--accent);letter-spacing:.02em}

/* 概览数字排在说明那句里（原来它是卡右侧的一排大字）。
   b 要还原成正文 —— 否则会被 .hmCard b 的「衬线 20px 标题」接管，
   句子中间突然冒出四个标题字。 */
.hmCard .hmStatLine b{
  font-family:inherit;font-size:inherit;font-weight:600;color:var(--ink);
  font-variant-numeric:tabular-nums;
}

.hmBlocks h2,.hmRecent h2,.hmTags h2,.hmFollow h2,.hmMajors h2{
  font-size:12px;letter-spacing:.22em;color:var(--muted);
  text-transform:uppercase;font-weight:600;margin-bottom:16px;
}

/* ============================================================
   十六大类目录（2026-10-06）
   ------------------------------------------------------------
   首页的主体，也是全站总目录。一行一类：序号 + 类名 + 存量 + 状态标记。
   桌面两栏（16 条 = 8 行），手机一栏 —— 390px 宽排两栏的话每栏只剩 175px，
   「省部共建农产品产地市场研究」这种 13 字的名字会被挤断行。
   （规划文档写的是「手机档折成两列」，按实际宽度算下来排不下，这里反过来。）
   序号用等宽数字，`min-width` 按两位数字定，六行才不会左右跳。
   ============================================================ */
.hmMajorWrap{
  display:grid;grid-template-columns:1fr 1fr;
  gap:0 clamp(20px,3vw,46px);
  border-top:1px solid var(--line);
}
.hmMajor{
  position:relative;display:grid;
  grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:baseline;gap:clamp(10px,1.4vw,20px);
  padding:9px 6px 9px 14px;border-bottom:1px solid var(--line);
  transition:background .2s,color .2s;
  animation:pop .5s var(--ease) both;
}
/* 左边一小截分类色，跟类别速览同一个语言 */
.hmMajor::after{
  content:"";position:absolute;left:0;top:11px;bottom:11px;width:3px;border-radius:2px;
  background:var(--line2);opacity:1;transition:background .2s;
}
.hmMajor[data-st="live"]::after{background:var(--ok)}
.hmMajor[data-st="updating"]::after{background:var(--accent2)}
.hmMajor i{
  font-style:normal;font-size:12px;letter-spacing:.14em;min-width:2.2ch;
  color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums;
}
.hmMajor b{font-family:var(--serif);font-size:18px;font-weight:600;line-height:1.35;min-width:0}
.hmMajor em{
  font-style:normal;font-size:12.5px;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums;text-align:right;
}
.hmMajor .st{
  font-size:12px;font-weight:600;padding:2px 9px;border-radius:99px;
  white-space:nowrap;letter-spacing:.02em;
}
.st-live{background:#e9f1e8;color:var(--ok)}
.st-updating{background:#f7efd6;color:var(--accent2-ink)}
.st-building{background:var(--paper-up);color:var(--muted);box-shadow:inset 0 0 0 1px var(--line)}
.hmMajor:hover{border-color:var(--line);background:color-mix(in srgb,var(--accent) 5%,transparent)}
.hmMajor:hover b{color:var(--accent)}
.hmMajor:hover i{color:var(--ink2)}

@media (max-width:760px){
  /* 手机一栏。名字最长 19 字，390px 下会自动换行，行高放到 1.4 更好读。 */
  .hmMajorWrap{grid-template-columns:1fr}
  .hmMajor{grid-template-columns:auto minmax(0,1fr) auto;gap:8px 12px;padding:11px 4px 11px 14px}
  .hmMajor b{font-size:16px}
  .hmMajor em{grid-column:2;text-align:left}   /* 存量数字挪到第二行，与类名左对齐 */
  .hmMajor .st{grid-column:3;grid-row:1}
}
/* 类别速览：杂志目录式（P1-1）。
   原来六张等高小卡片，2 行 × 108px = 235px 高 —— 体量差异（15 个细分主题 vs 7 个）
   在等高卡里看不出来，而且太占高度，把「最新发布」顶到折叠线以下。
   现在改成两栏目录条目：左序号（衬线）+ 类名 + 右对齐计数，行间一条细分隔线，
   hover 整行出底色、类名转主色。六条排 3 行，高度砍掉一半。 */
.hmChips{
  display:grid;grid-template-columns:1fr 1fr;
  gap:0 clamp(20px,3vw,46px);
  border-top:1px solid var(--line);
}
.hmChip{
  position:relative;display:grid;grid-template-columns:auto 1fr auto;
  align-items:baseline;gap:clamp(12px,1.6vw,22px);
  background:none;border:0;border-bottom:1px solid var(--line);border-radius:0;
  box-shadow:none;padding:11px 6px 11px 14px;
  transition:background .2s,color .2s;
  animation:pop .5s var(--ease) both;
}
/* 左边那道分类色：从整条色带收成一小截，目录里够用 */
.hmChip::after{
  content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;border-radius:2px;
  background:var(--c,var(--accent));opacity:.85;
}
.hmChip i{
  font-style:normal;font-size:12px;letter-spacing:.14em;min-width:2.2ch;
  color:var(--c,var(--accent));font-weight:600;font-variant-numeric:tabular-nums;
}
.hmChip b{font-family:var(--serif);font-size:19px;font-weight:600;line-height:1.35;min-width:0}
.hmChip span{font-size:12.5px;color:var(--muted);text-align:right;white-space:nowrap}
.hmChip:hover{border-color:var(--line);transform:none;
  background:color-mix(in srgb,var(--accent) 5%,transparent)}
.hmChip:hover b{color:var(--accent)}
.hmList{display:flex;flex-direction:column}

/* 标签区：胶囊，横排自动换行。数量角标只在有文章挂上去时才出。 */
.hmTagWrap{display:flex;flex-wrap:wrap;gap:9px}
.hmTag{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 14px;border-radius:999px;
  background:var(--paper);border:1px solid var(--line);
  color:var(--ink2);font-size:13px;line-height:1.4;
  transition:border-color .2s,color .2s,transform .28s var(--ease),box-shadow .28s;
}
.hmTag:hover{
  border-color:transparent;color:var(--accent);transform:translateY(-2px);
  box-shadow:0 14px 28px -22px rgba(var(--shade),.62);
}
.hmTag i{font-style:normal;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.hmTag:hover i{color:var(--accent);opacity:.75}

/* 首页的关注块：两个二维码并排 */
#hmFollow{display:flex;flex-wrap:wrap;gap:clamp(16px,2.4vw,30px);align-items:center;
  padding:clamp(20px,3vw,30px);background:var(--paper);border:1px solid var(--line);
  border-radius:16px}
#hmFollow .txt{flex:1 1 260px;min-width:220px}
#hmFollow .txt b{font-family:var(--serif);font-size:19px;font-weight:600;display:block;margin-bottom:8px}
#hmFollow .txt p{color:var(--muted);font-size:13.5px;line-height:1.85}
#hmFollow .qrs{display:flex;gap:18px;flex-wrap:wrap}

/* ============================================================
   七、二维码（浮层与首页共用）
   ============================================================ */
.qrCard{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  background:var(--paper);border:1px solid var(--line);border-radius:15px;
  padding:16px 16px 13px;
}
.qrCard .qrImg{
  width:188px;height:188px;border-radius:10px;background:#ffffff;padding:9px;
  display:grid;place-items:center;
}
.qrCard .qrImg img{width:100%;height:100%;object-fit:contain;display:block}
.qrCard figcaption{font-size:12.5px;color:var(--ink2);text-align:center;line-height:1.6}
.qrCard figcaption b{display:block;font-size:14px;font-weight:600;color:var(--ink)}
.qrCard figcaption span{color:var(--muted);font-variant-numeric:tabular-nums}

/* ============================================================
   八、流通地图类别
   ============================================================ */
.mvHead,.mvCol,.mvSub{max-width:900px;margin-left:auto;margin-right:auto}
.mvHead{margin-bottom:clamp(20px,3.2vh,38px)}
.mvHead h1{font-family:var(--serif);font-weight:600;font-size:clamp(27px,3.1vw,40px);line-height:1.3}
.mvHead p{margin-top:12px;color:var(--ink2);font-size:14.5px;max-width:66ch}

.mvStage{
  position:relative;margin:0;border:1px solid var(--line);border-radius:18px;overflow:hidden;
  background:
    radial-gradient(126% 104% at 44% 32%,
      var(--paper-up) 0%,
      color-mix(in srgb,var(--accent) 4.5%,var(--paper)) 58%,
      color-mix(in srgb,var(--accent) 9%,var(--paper)) 100%);
  box-shadow:0 16px 44px -36px rgba(var(--shade),.6);
  animation:pop .62s var(--ease) both;
}
/* 画布要压在插图外框之上，否则那层半透明白底会把岛和九段线洗淡 */
#mvMap{position:relative;z-index:2;width:100%;cursor:grab;touch-action:none;
  height:clamp(404px,56vh,566px)}
#mvMap.grabbing{cursor:grabbing}

/* 插图的托盘与边框现在由画布的「范围框」要素画（放大后主图会盖到右下角，
   DOM 在画布下面挡不住）；这里只留「南海诸岛」四个字 */
#mvInsetLb{position:absolute;pointer-events:none;z-index:3;
  font-size:12px;color:var(--muted-ink);letter-spacing:.04em}

/* 缩放工具条：右上角，别压到右下角的南海诸岛插图 */
.mvTools{
  position:absolute;right:16px;top:12px;z-index:4;
  display:flex;flex-direction:row;gap:8px;
}
.mvTools button{
  width:34px;height:34px;border-radius:10px;background:var(--surface);border:1px solid var(--line2);
  color:var(--ink2);font-size:17px;line-height:1;display:grid;place-items:center;
  box-shadow:0 6px 18px -12px rgba(var(--shade),.7);
  transition:border-color .2s,color .2s,transform .2s,background .3s;
}
.mvTools button:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
.mvTools button svg{width:15px;height:15px}

/* 图层面板：地图右侧，默认全部关闭 */
#mvLayers{
  position:absolute;right:16px;top:54px;z-index:4;width:216px;
  background:color-mix(in srgb,var(--surface) 90%,transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid var(--line);border-radius:14px;padding:8px;
  box-shadow:0 16px 40px -32px rgba(var(--shade),.8);
}
.lyHead{display:flex;align-items:center;gap:8px;padding:3px 6px 7px;
  border-bottom:1px solid var(--line);margin-bottom:5px}
.lyHead b{font-size:12px;letter-spacing:.2em;color:var(--muted);font-weight:600;text-transform:uppercase}
.lyHead button{
  margin-left:auto;font-size:12px;color:var(--accent);padding:3px 8px;border-radius:999px;
  border:1px solid var(--line);transition:border-color .2s;
}
.lyHead button:hover{border-color:var(--accent)}
.lyRow{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  padding:6px 7px;border-radius:9px;transition:background .2s;
}
.lyRow:hover{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.lyRow .dot{
  flex:none;width:11px;height:11px;border-radius:50%;
  background:var(--c);border:1px solid var(--mv-mark-ring);
}
.lyRow .dot.dia{border-radius:2px;transform:rotate(45deg) scale(.94)}
.lyRow .nm{flex:1;min-width:0;font-size:12.5px;line-height:1.4;color:var(--ink2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lyRow .n{flex:none;white-space:nowrap;font-size:12px;color:var(--muted);
  font-variant-numeric:tabular-nums}
.lyRow .sw{
  flex:none;width:30px;height:17px;border-radius:999px;position:relative;
  background:var(--line2);transition:background .24s;
}
.lyRow .sw::after{
  content:"";position:absolute;left:2px;top:2px;width:13px;height:13px;border-radius:50%;
  background:var(--surface);box-shadow:0 1px 3px rgba(var(--shade),.4);
  transition:transform .24s var(--ease);
}
.lyRow.on .nm{color:var(--ink);font-weight:600}
.lyRow.on .sw{background:var(--c)}
.lyRow.on .sw::after{transform:translateX(13px)}
.lyRow.on .dot{box-shadow:0 0 0 4px color-mix(in srgb,var(--c) 24%,transparent)}

.mvBar{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:12px 18px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--muted);
}
.mvBar b{color:var(--ink);font-weight:600}
.mvBar .mvPct{margin-left:auto;font-variant-numeric:tabular-nums;color:var(--ink2);font-weight:600}
.mvBar .mvHint{letter-spacing:.04em}

.mvCap{margin-top:14px;font-size:12px;color:var(--muted);line-height:1.85;max-width:78ch}

.mvSub{margin-top:clamp(30px,4.6vh,50px)}
.mvSub h2{
  margin-bottom:14px;font-size:12px;letter-spacing:.22em;color:var(--muted);
  text-transform:uppercase;font-weight:600;
}
.mvSubGrid{display:grid;gap:clamp(13px,1.6vw,20px);grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.mvCard{
  position:relative;display:flex;align-items:center;overflow:hidden;
  background:var(--paper);border:1px dashed var(--line2);border-radius:15px;
  padding:22px;animation:pop .6s var(--ease) both;
}
.mvCard b{font-family:var(--serif);font-size:15.5px;font-weight:600;line-height:1.5}
.mvCard em{
  position:absolute;right:16px;top:14px;font-style:normal;
  font-size:12px;letter-spacing:.08em;color:var(--accent2-ink);
}

/* ============================================================
   九、层级目录：浮在底部导航上侧，一级一行
   ============================================================ */
#path{
  position:fixed;left:clamp(16px,3.2vw,44px);bottom:calc(var(--dockH) + 14px);
  z-index:38;width:min(318px,calc(100vw - 32px));
  max-height:min(46vh,430px);
  display:flex;flex-direction:column;
  background:color-mix(in srgb,var(--surface) 94%,transparent);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line);border-radius:15px;
  box-shadow:0 22px 54px -40px rgba(var(--shade),.9);
  animation:pathIn .42s var(--ease) both;
}
@keyframes pathIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
#path .pHd{
  display:flex;align-items:center;gap:8px;flex:none;
  padding:9px 10px 8px 13px;border-bottom:1px solid var(--line);
}
#path .pHd b{font-size:12px;letter-spacing:.2em;color:var(--muted);font-weight:600;text-transform:uppercase}
#path .pHd .pCrumb{
  margin-left:auto;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;
}
#path .pTog{
  width:24px;height:24px;border-radius:8px;color:var(--muted);display:grid;place-items:center;
  transition:transform .3s var(--ease),color .2s;
}
#path .pTog:hover{color:var(--ink);background:var(--line)}
#path .pTog svg{width:15px;height:15px}
#path.min .pTog{transform:rotate(180deg)}
#path.min #pathList{display:none}
#path.min .pHd{border-bottom:0}
#pathList{list-style:none;overflow:auto;padding:6px}
.pRow{
  display:flex;align-items:center;gap:9px;width:100%;text-align:left;
  padding:8px 10px;border-radius:10px;position:relative;
  transition:background .2s;
  animation:pop .42s var(--ease) both;
}
.pRow:hover{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.pRow .pDot{
  flex:none;width:8px;height:8px;border-radius:50%;
  background:var(--c,var(--accent));opacity:.5;transition:opacity .2s,transform .2s;
}
.pRow .pKind{
  flex:none;white-space:nowrap;font-size:12px;letter-spacing:.1em;color:var(--muted);
}
.pRow .pName{flex:1;min-width:0;font-size:13.5px;line-height:1.4;color:var(--ink2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pRow .pN{flex:none;white-space:nowrap;font-size:12px;color:var(--muted);
  font-variant-numeric:tabular-nums}
.pRow.on{background:color-mix(in srgb,var(--accent) 10%,transparent)}
.pRow.on .pName{color:var(--ink);font-weight:600}
.pRow.on .pDot{opacity:1;transform:scale(1.25)}
.pRow.on::before{
  content:"";position:absolute;left:0;top:8px;bottom:8px;width:2px;border-radius:2px;
  background:var(--c,var(--accent));
}
#path.min .pRow.on::before{display:none}

/* ============================================================
   十、底部导航（只有内容页有）+ 版权行
   ============================================================ */
#dock{
  position:fixed;left:0;right:0;bottom:var(--footH);z-index:39;
  background:color-mix(in srgb,var(--paper) 92%,transparent);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-top:1px solid var(--line);
}
#dockTop{
  display:flex;align-items:center;gap:18px;
  max-width:1180px;margin:0 auto;padding:12px clamp(16px,3.2vw,44px) 10px;
}
#board{position:relative;display:flex;gap:26px;flex-wrap:wrap}
#board a{
  position:relative;padding:4px 2px 12px;font-size:14px;color:var(--muted);
  letter-spacing:.02em;transition:color .2s;white-space:nowrap;cursor:pointer;
}
#board a:hover{color:var(--ink2)}
#board a.on{color:var(--ink);font-weight:600}
#boardInk{
  position:absolute;bottom:4px;height:2px;border-radius:2px;background:var(--accent);
  transition:left .34s var(--ease),width .34s var(--ease);
}
#footWrap{
  position:fixed;left:0;right:0;bottom:0;z-index:40;
  background:color-mix(in srgb,var(--paper) 94%,transparent);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
}
#footBar{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  max-width:1180px;margin:0 auto;padding:9px clamp(16px,3.2vw,44px) 11px;
  border-top:1px solid var(--line);
  font-size:12px;color:var(--muted);
}
#dock + #footWrap #footBar{border-top:0}
#footBar .l,#footBar .r{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#footBar .sep{color:var(--line2)}
#footBar a,#footBar button{color:var(--muted);transition:color .2s;font-size:12px}
#footBar a:hover,#footBar button:hover{color:var(--accent)}
#footBar .fl{display:inline-flex;align-items:center;gap:5px}
#footBar .fl svg{width:13px;height:13px;opacity:.8}

/* 悬停出码：鼠标移到「微信」或「关注飞鸿品农」上，就在页脚上方浮出二维码。
   点「关注飞鸿品农」仍走原来的大浮层（手机上没有悬停，得留一条路）。 */
#footBar .footQr{position:relative;display:inline-flex;align-items:center}
#footBar .footQr > .lbl{cursor:default}
#footBar .footQr > .pop{
  position:absolute;left:50%;bottom:calc(100% + 13px);z-index:2;
  transform:translateX(-50%) translateY(7px);
  width:168px;padding:9px 9px 8px;border-radius:14px;
  background:var(--surface);border:1px solid var(--line);
  box-shadow:0 20px 48px -26px rgba(var(--shade),.72);
  text-align:center;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .2s var(--ease),transform .2s var(--ease),visibility .2s;
}
#footBar .footQr > .pop::after{          /* 朝下的小尖角，指回触发它的那个词 */
  content:"";position:absolute;left:50%;top:100%;width:9px;height:9px;margin:-5px 0 0 -5px;
  background:var(--surface);border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  transform:rotate(45deg);
}
#footBar .footQr > .pop img{display:block;width:148px;height:148px;border-radius:8px}
#footBar .footQr > .pop i{display:block;margin-top:7px;font-style:normal;font-size:12px;color:var(--muted);line-height:1.5}
#footBar .footQr:hover > .pop,
#footBar .footQr:focus-within > .pop{
  opacity:1;visibility:visible;pointer-events:auto;
  transform:translateX(-50%) translateY(0);
}

/* ============================================================
   十一、浮层：关于我 / 关注 / 文章
   ============================================================ */
.mask{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  background:color-mix(in srgb,var(--ink) 38%,transparent);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  animation:fade .24s ease both;padding:18px;
}
@keyframes fade{from{opacity:0}to{opacity:1}}
.mask .box{
  width:min(560px,94vw);max-height:90vh;max-height:90dvh;overflow:auto;position:relative;
  background:var(--surface);border:1px solid var(--line);
  border-radius:18px;padding:34px 36px 30px;
  box-shadow:0 30px 80px -40px rgba(var(--shade),.9);
  animation:pop .4s var(--ease) both;
}
.mask .x{
  position:absolute;right:16px;top:14px;width:32px;height:32px;border-radius:50%;
  color:var(--muted);font-size:17px;display:grid;place-items:center;z-index:2;
  transition:background .2s,color .2s,transform .3s var(--ease);
}
.mask .x:hover{background:var(--line);color:var(--ink);transform:rotate(90deg)}
.mask h2{font-family:var(--serif);font-size:22px;font-weight:600;margin-bottom:14px}
.mask p{color:var(--ink2);font-size:14px;line-height:1.9;margin-bottom:10px}

#about .wx{
  display:flex;align-items:center;gap:10px;margin-top:16px;padding:12px 16px;
  border:1px solid var(--line);border-radius:12px;background:var(--paper);font-size:13.5px;
}
#about .wx b{font-variant-numeric:tabular-nums}
#about .gen{margin-top:18px;font-size:12px;color:var(--muted)}
/* P1-2：手机档页脚撤下来的那五项（关注 / 版权 / 备案号）落在「关于我」里。
   桌面档页脚本来就有，这里收起来不重复。 */
.footIn{display:none}
#about .footIn{display:none;margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
#about .fiRow{display:flex;align-items:center;flex-wrap:wrap;gap:10px;font-size:12.5px;color:var(--muted)}
#about .fiRow + .fiRow{margin-top:10px}
#about .fiBtn{
  display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 13px;
  border:1px solid var(--line);border-radius:999px;color:var(--ink2);
  transition:border-color .2s,color .2s;
}
#about .fiBtn:hover{border-color:var(--accent);color:var(--accent)}
#about .fiBtn svg{width:15px;height:15px;opacity:.85}
#about .fiLegal .sep{color:var(--line2)}
#about .fiLegal a{color:var(--muted)}
#about .fiLegal a:hover{color:var(--accent)}
#about .who{display:flex;align-items:center;gap:14px;margin-bottom:16px}
#about .who img{height:46px;width:auto}
#about .who .av{width:52px;height:52px;border-radius:50%;object-fit:cover}

#follow .fHead{display:flex;align-items:center;gap:13px;margin-bottom:16px}
#follow .fHead img{height:44px;width:auto}
#follow .fHead h2{margin:0;font-size:21px}
#follow .qrs{display:flex;gap:20px;flex-wrap:wrap;justify-content:center;margin-top:6px}

/* 文章浮窗：整块滚，不再做嵌套滚动区（正文长、评论长都一起滚更顺手） */
#post .box{
  width:min(900px,95vw);max-height:90vh;max-height:90dvh;padding:0;display:block;
}
#post .pHead{
  padding:26px clamp(20px,3vw,38px) 16px;
  border-bottom:1px solid var(--line);
}
#post .pKind{
  font-size:12px;letter-spacing:.2em;color:var(--muted);
  text-transform:uppercase;margin-bottom:10px;
}
#post .pTitle{
  font-family:var(--serif);font-size:clamp(20px,2.4vw,27px);font-weight:600;line-height:1.4;
}
#post .pMeta{margin-top:10px;font-size:12.5px;color:var(--muted);display:flex;gap:14px;flex-wrap:wrap}
#post .pMeta .chip{
  display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:999px;
  border:1px solid var(--line);color:var(--ink2);font-size:12px;
}
#post .pBack{
  display:inline-flex;align-items:center;gap:6px;margin-bottom:14px;
  font-size:12.5px;color:var(--accent);
}
#post .pBack svg{width:13px;height:13px}
#post .pBody{
  padding:22px clamp(20px,3vw,38px) 20px;
  font-size:15px;line-height:1.95;color:var(--ink2);
}
#post .pBody h2,#post .pBody h3,#post .pBody h4{
  font-family:var(--serif);color:var(--ink);font-weight:600;
  margin:1.5em 0 .6em;line-height:1.45;
}
#post .pBody h2{font-size:21px} #post .pBody h3{font-size:18px} #post .pBody h4{font-size:16px}
#post .pBody p{margin:0 0 1.05em}
#post .pBody a{color:var(--accent);border-bottom:1px solid color-mix(in srgb,var(--accent) 34%,transparent)}
#post .pBody ul,#post .pBody ol{margin:0 0 1.05em 1.35em}
#post .pBody li{margin-bottom:.45em}
#post .pBody img{height:auto;border-radius:12px;display:block;margin:1.1em auto}
#post .pBody blockquote{
  margin:1.1em 0;padding:10px 16px;border-left:3px solid var(--accent);
  background:color-mix(in srgb,var(--accent) 5%,transparent);border-radius:0 10px 10px 0;
  color:var(--ink2);
}
#post .pBody code{background:var(--line);border-radius:5px;padding:1px 6px;font-size:.9em}
#post .pBody table{width:100%;border-collapse:collapse;margin:1.1em 0;font-size:13.5px}
#post .pBody th,#post .pBody td{border:1px solid var(--line);padding:7px 11px;text-align:left}
#post .pBody th{background:var(--paper);color:var(--ink);font-weight:600}
#post .pBody figure{margin:1.2em 0}
#post .pBody figcaption{font-size:12.5px;color:var(--muted);text-align:center;margin-top:6px}
/* 浮窗里的文章本来就住在一个卡片里，正文自带的 .wrap 壳不再套第二个框，
   只把宽度限制与内边距卸掉，排版交给 .pBody。 */
#post .pBody .fhn-art{background:transparent;color:inherit}
#post .pBody .fhn-art .wrap{
  max-width:none;margin:0;padding:0;border:0;border-radius:0;
  background:transparent;box-shadow:none;
}
/* 相关阅读在浮窗里要压过 #post .pBody h2 那条规则，否则标题会顶成 21px 衬线 */
#post .pBody .sRec{margin-top:34px}
#post .pBody .sRecH{
  font-family:var(--serif);font-size:15px;font-weight:600;color:var(--ink);
  margin:0 0 14px;padding:0;border:0;line-height:1.5;
}
#post .pBody .sRecH::after{content:"";flex:1;height:1px;background:var(--line)}

/* 文末声明在浮窗里同样要压过 #post .pBody 那几条（h2 / ul / li / p 都比
   .sDisc* 高一级），不然标题会顶成 21px 衬线、列表还会多出缩进。 */
#post .pBody .sDisc{margin-top:30px;padding:14px 16px 13px}
#post .pBody .sDiscH{
  font-family:var(--serif);font-size:13px;font-weight:600;color:var(--ink2);
  margin:0 0 9px;padding:0;border:0;line-height:1.5;
}
#post .pBody .sDiscL{margin:0;padding:0;list-style:none}
#post .pBody .sDiscL li{margin:0;font-size:12px;line-height:1.8}
#post .pBody .sDiscM{margin:11px 0 0;padding:10px 0 0;font-size:12px}

/* 点位卡片（从地图点进来时的抬头） */
#post .pPoi{
  display:flex;flex-wrap:wrap;gap:8px 18px;align-items:baseline;
  padding:14px 16px;border:1px solid var(--line);border-radius:13px;background:var(--paper);
  margin-bottom:18px;
}
#post .pPoi .pn{font-family:var(--serif);font-size:17px;font-weight:600;color:var(--ink)}
#post .pPoi .pt{font-size:12.5px;color:var(--muted)}
#post .pPoi .pc{font-size:12.5px;color:var(--muted);flex-basis:100%}
#post .pPoi b{color:var(--ink);font-weight:600}

/* 评论区 */
#post .cmt{
  border-top:1px solid var(--line);
  padding:20px clamp(20px,3vw,38px) 26px;
  background:var(--paper);
}
#post .cmt h3{
  font-size:12px;letter-spacing:.2em;color:var(--muted);text-transform:uppercase;
  font-weight:600;margin-bottom:14px;display:flex;align-items:center;gap:9px;
}
#post .cmt h3 b{color:var(--ink);font-size:14px;letter-spacing:0;font-variant-numeric:tabular-nums}
.cmtList{list-style:none;display:flex;flex-direction:column;gap:14px;margin-bottom:18px}
.cmtList li{
  display:flex;gap:11px;padding-bottom:14px;border-bottom:1px solid var(--line);
}
.cmtList li:last-child{border-bottom:0;padding-bottom:0}
.cmtList .cmAv{
  flex:none;width:32px;height:32px;border-radius:50%;object-fit:cover;background:var(--line);
}
.cmtList .cmMain{flex:1;min-width:0}
.cmtList .cmWho{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;margin-bottom:4px}
.cmtList .cmWho b{font-size:13px;font-weight:600;color:var(--ink)}
.cmtList .cmWho time{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.cmtList .cmWho .rep{font-size:12px;color:var(--accent)}
.cmtList .cmBody{font-size:13.5px;line-height:1.85;color:var(--ink2);word-break:break-word}
.cmtList .cmBody p{margin:0 0 .5em}
.cmtList .cmBody p:last-child{margin-bottom:0}
/* 嵌套回复是 .cmMain 里的 ol.children：li 是 flex 行，放在 li 下会跟主评论并排，
   而且 <ol> 不写 list-style 会冒出序号 */
.cmtList ol.children{
  list-style:none;margin:12px 0 0 0;padding-left:12px;
  border-left:2px solid var(--line);display:flex;flex-direction:column;gap:12px;
}
.cmtEmpty{font-size:13px;color:var(--muted);line-height:1.8;margin-bottom:16px}
.cmtForm{display:flex;flex-direction:column;gap:10px}
.cmtForm .cfRow{display:flex;gap:10px;flex-wrap:wrap}
.cmtForm input,.cmtForm textarea{
  font:inherit;font-size:13.5px;color:var(--ink);background:var(--surface);
  border:1px solid var(--line2);border-radius:10px;padding:9px 12px;outline:none;
  transition:border-color .2s,box-shadow .2s,background .3s;
}
.cmtForm input{flex:1 1 160px;min-width:0}
.cmtForm input:focus,.cmtForm textarea:focus{
  border-color:color-mix(in srgb,var(--accent) 46%,var(--line2));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 10%,transparent);
}
.cmtForm textarea{width:100%;min-height:96px;resize:vertical;line-height:1.75}
.cmtForm .cfFt{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cmtForm .cfFt .note{font-size:12px;color:var(--muted)}
.cmtForm .cfSend{
  height:36px;padding:0 20px;border-radius:999px;background:var(--accent);color:var(--on-accent);
  font-size:13px;transition:filter .2s;
}
.cmtForm .cfSend:hover{filter:brightness(1.08)}
.cmtForm .cfSend[disabled]{opacity:.5;cursor:not-allowed}
.cmtForm select{
  font:inherit;font-size:13px;color:var(--ink2);background:var(--surface);
  border:1px solid var(--line2);border-radius:10px;padding:8px 10px;
}
#cmtFrame{width:0;height:0;border:0;position:absolute;left:-9999px}

/* ============================================================
   十二、归档页
   ============================================================ */
#feed{max-width:1180px;width:100%;margin:0 auto;flex:1 0 auto}
/* P1-1：行内边距 14 → 12、行距 8 → 6。一条行框从 62px 收到 56px，
   三条正好落进首屏（1440×900 下第三条底边 886px）。 */
.postRow{
  display:flex;align-items:baseline;gap:14px;padding:12px 18px;margin-bottom:6px;
  border:1px solid var(--line);border-radius:12px;background:var(--paper);
  transition:border-color .2s,transform .3s var(--ease),background .3s;
}
.postRow:hover{border-color:var(--line2);transform:translateX(4px)}
.postRow .t{flex:1;font-size:14.5px;line-height:1.6;font-weight:600}
.postRow .e{flex:none;font-size:12.5px;color:var(--muted);max-width:44ch;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.pager{margin-top:22px}
.pager .nav-links{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;font-size:13px}
.pager a,.pager span.current,.pager span.dots{
  min-width:36px;height:36px;padding:0 12px;border-radius:10px;
  border:1px solid var(--line);background:var(--paper);color:var(--ink2);
  display:inline-flex;align-items:center;justify-content:center;
}
.pager a:hover{border-color:var(--accent);color:var(--accent)}
.pager span.current{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}

/* ============================================================
   十三、单篇文章页（single.php）
   ------------------------------------------------------------
   线上文章是从本地论文 HTML 推进来的，正文自带一层 .fhn-art / .wrap
   外壳（宽度写死 740、白底、自带内边距）。原来 #single 是 820，
   比那层壳宽 40，标题左边缘就和正文框差出一条边——看着就是「没对齐」。
   这里的口径：**#single 收成 780，正文壳撑满这一列**，于是
   标题、正文框、关键词、推荐区共用同一条左边线。
   ============================================================ */
#single{max-width:780px;width:100%;margin:0 auto;flex:1 0 auto}
#single .sHead{margin-bottom:clamp(20px,3vw,34px)}
#single .sTitle{
  font-family:var(--serif);font-size:clamp(25px,3.4vw,38px);font-weight:600;line-height:1.34;
}
#single .sMeta{display:flex;gap:14px;flex-wrap:wrap;margin-top:14px;font-size:12.5px;color:var(--muted)}
#single .sMeta a{color:var(--accent)}
#single .sBody{font-size:15.5px;line-height:2;color:var(--ink2)}

/* 正文框：细线框取代原来那圈白底。
   自带 CSS 用 .fhn-art .wrap（两个类）定宽定色，这里靠 #single + 三层类压过去，
   比它高一级，不需要 !important。 */
#single .sBody .fhn-art{background:transparent;color:inherit}
#single .sBody .fhn-art .wrap{
  max-width:none;margin:0;background:var(--surface);
  border:1px solid var(--line);border-radius:16px;
  padding:26px clamp(18px,3.2vw,34px) 42px;
}
/* 手工在后台直接写的文章没有 .fhn-art 壳，给一个同样的框，两处长得一样 */
#single .sBody:not(:has(.fhn-art)){
  background:var(--surface);border:1px solid var(--line);border-radius:16px;
  padding:26px clamp(18px,3.2vw,34px) 42px;
}

#single .sBody h2,#single .sBody h3,#single .sBody h4{
  font-family:var(--serif);color:var(--ink);font-weight:600;margin:1.6em 0 .6em;line-height:1.45;
}
#single .sBody h2{font-size:23px} #single .sBody h3{font-size:19px} #single .sBody h4{font-size:17px}
#single .sBody p{margin:0 0 1.1em}
#single .sBody a:not(.kwt){color:var(--accent);border-bottom:1px solid color-mix(in srgb,var(--accent) 34%,transparent)}
/* 正文里「关键词」那行胶囊换成链接后，要保住它原本的胶囊外观。
   两条硬规矩：
   1）通用链接样式用 :not(.kwt) 排除胶囊，别让 accent 色和下边框冲掉它；
   2）这里**绝对不写 color**。正文自带的 .kwt 颜色亮色下已经对，暗色下由
      :root[data-theme="dark"] .fhn-art .kwt 接管。一旦在这写了死色值，
      ID 权重会压过那条暗色规则 —— 暗色下就是深绿字压深底，整排关键词看不见。 */
#single .sBody a.kwt{border-bottom:none;text-decoration:none;transition:background .18s,border-color .18s}
#single .sBody a.kwt:hover{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent)}
#single .sBody ul,#single .sBody ol{margin:0 0 1.1em 1.4em}
#single .sBody img{height:auto;border-radius:12px;display:block;margin:1.2em auto}
#single .sBody blockquote{
  margin:1.2em 0;padding:12px 18px;border-left:3px solid var(--accent);
  background:color-mix(in srgb,var(--accent) 5%,transparent);border-radius:0 10px 10px 0;
}
#single .sBody table{width:100%;border-collapse:collapse;margin:1.2em 0;font-size:14px}
#single .sBody th,#single .sBody td{border:1px solid var(--line);padding:8px 12px;text-align:left}
#single .sBody th{background:var(--paper);color:var(--ink);font-weight:600}
#single .sBody figcaption,.wp-caption-text{font-size:12.5px;color:var(--muted);text-align:center;margin-top:6px}
#single .sTags{
  margin-top:30px;padding-top:20px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
}
#single .sTagsK{font-size:12.5px;color:var(--muted);margin-right:2px}
#single .sTags a{
  display:inline-flex;align-items:center;padding:4px 12px;border-radius:999px;
  border:1px solid var(--line);color:var(--ink2);font-size:12.5px;line-height:1.6;
  transition:border-color .18s,color .18s,background .18s;
}
#single .sTags a:hover{
  border-color:var(--accent);color:var(--accent);
  background:color-mix(in srgb,var(--accent) 6%,transparent);
}
#single .sPrev{margin-top:34px;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;
  font-size:13px;color:var(--muted)}
#single .sPrev a{color:var(--accent)}

/* ---------------- 文末声明（文章页 + 浮窗，同 single.php / inc/data.php） ----------------
   排在正文与关键词之后、相关阅读之前：正文和它自己的关键词是一组，
   相关阅读属于「接着读」的引导，声明夹在这两段之间最顺。
   颜色只走令牌，夜间模式跟着换；对比度按 .sDiscL 里的 muted 走，够 3:1。 */
.sDisc{
  margin-top:clamp(26px,4vh,40px);
  padding:16px 18px 15px;border-radius:13px;
  border:1px solid var(--line);
  background:color-mix(in srgb,var(--ink) 4%,var(--paper));
}
.sDiscH{
  font-family:var(--serif);font-size:13px;font-weight:600;
  letter-spacing:.14em;color:var(--ink2);margin-bottom:9px;
}
.sDiscL{list-style:none;display:grid;gap:6px;margin:0}
.sDiscL li{
  position:relative;padding-left:15px;margin:0;
  font-size:12.5px;line-height:1.85;color:var(--muted);
}
.sDiscL li::before{
  content:"";position:absolute;left:2px;top:.74em;
  width:4px;height:4px;border-radius:50%;
  background:color-mix(in srgb,var(--muted) 62%,transparent);
}
.sDiscM{
  margin:11px 0 0;padding-top:10px;
  border-top:1px solid var(--line);
  font-size:12.5px;color:var(--muted);
}
.sDiscM b{color:var(--ink2);font-weight:600;letter-spacing:.02em}

/* ---------------- 相关阅读（同标签 + 同分类） ----------------
   文章页与浮窗共用一套类名，两处长得一样。
   **两列、只给文章名** —— 日期与「同标签/同类型」标签都不上：
   一屏能多放几条，也不会有「标题 + 来源 + 日期」在窄格里挤成一串。 */
.sRec{margin-top:clamp(30px,4.4vh,48px)}
.sRecH{
  font-family:var(--serif);font-size:15px;font-weight:600;color:var(--ink);
  display:flex;align-items:center;gap:10px;margin-bottom:14px;
}
.sRecH::after{content:"";flex:1;height:1px;background:var(--line)}
.sRecList{
  list-style:none;display:grid;gap:9px;
  grid-template-columns:repeat(2,minmax(0,1fr));
}
.sRecList > li{display:flex}
.sRecList > li > a,.sRecList > li > button{
  display:flex;align-items:flex-start;width:100%;height:100%;text-align:left;
  padding:12px 14px;border:1px solid var(--line);border-radius:11px;
  background:var(--paper);text-decoration:none;color:inherit;
  transition:border-color .2s,transform .26s var(--ease),background .3s;
}
.sRecList > li > a:hover,.sRecList > li > button:hover{
  border-color:color-mix(in srgb,var(--accent) 46%,var(--line));
  transform:translateX(4px);
  background:color-mix(in srgb,var(--accent) 5%,var(--paper));
}
.sRecT{font-size:13.5px;line-height:1.65;color:var(--ink)}
/* 两列在窄屏会挤成一条细柱，排不下就塌成一列 */
@media (max-width:720px){
  .sRecList{grid-template-columns:1fr}
  .sRecList > li > a:hover,.sRecList > li > button:hover{transform:translateX(3px)}
}

/* ---------------- 正文自带 CSS 的夜间与窄屏收口 ----------------
   推进来的论文 HTML 里那套颜色是生成时就写死的浅色。这里把主色压回令牌，
   否则夜间模式下会出现一张白卡片压在深色页面上。 */
:root[data-theme="dark"] .fhn-art{color:var(--ink2)}
:root[data-theme="dark"] .fhn-art .wrap{background:var(--surface);color:var(--ink2)}
:root[data-theme="dark"] .fhn-art .topbar,
:root[data-theme="dark"] .fhn-art .abstract,
:root[data-theme="dark"] .fhn-art .ovb{border-left-color:var(--accent)}
:root[data-theme="dark"] .fhn-art .topbar{background:var(--accent)}
:root[data-theme="dark"] .fhn-art h1,
:root[data-theme="dark"] .fhn-art h2,
:root[data-theme="dark"] .fhn-art .fig-t,
:root[data-theme="dark"] .fhn-art .tbl-t,
:root[data-theme="dark"] .fhn-art .ovb-h{color:var(--accent)}
:root[data-theme="dark"] .fhn-art h2{border-left-color:var(--accent2)}
:root[data-theme="dark"] .fhn-art .meta,
:root[data-theme="dark"] .fhn-art .byline,
:root[data-theme="dark"] .fhn-art p.kw{color:var(--muted-ink)}
:root[data-theme="dark"] .fhn-art .byline,
:root[data-theme="dark"] .fhn-art .foot{border-color:var(--line)}
:root[data-theme="dark"] .fhn-art .abstract,
:root[data-theme="dark"] .fhn-art .ovb,
:root[data-theme="dark"] .fhn-art .tbl th,
:root[data-theme="dark"] .fhn-art .tbl tr.sum td{
  background:color-mix(in srgb,var(--accent) 15%,var(--surface));
}
:root[data-theme="dark"] .fhn-art .abstract b,
:root[data-theme="dark"] .fhn-art .kwt,
:root[data-theme="dark"] .fhn-art .gloss-i b{color:var(--accent)}
:root[data-theme="dark"] .fhn-art .kwt{
  background:color-mix(in srgb,var(--accent) 16%,var(--surface));border-color:var(--accent);
}
:root[data-theme="dark"] .fhn-art .concl{
  background:color-mix(in srgb,var(--accent2) 18%,var(--surface));
  border-left-color:var(--accent2);
}
:root[data-theme="dark"] .fhn-art .ovb-v,
:root[data-theme="dark"] .fhn-art .more{color:var(--accent2-ink)}
:root[data-theme="dark"] .fhn-art .pain{
  color:var(--err);background:color-mix(in srgb,var(--err) 15%,var(--surface));border-left-color:var(--err);
}
:root[data-theme="dark"] .fhn-art .dark,
:root[data-theme="dark"] .fhn-art .gloss{
  background:var(--surface-2);border-color:var(--line);
}
:root[data-theme="dark"] .fhn-art .solve{
  background:color-mix(in srgb,var(--ok) 15%,var(--surface));border-left-color:var(--ok);
}
:root[data-theme="dark"] .fhn-art .solve b{color:var(--ok)}
:root[data-theme="dark"] .fhn-art .more-a,
:root[data-theme="dark"] .fhn-art .more-r,
:root[data-theme="dark"] .fhn-art .tbl td,
:root[data-theme="dark"] .fhn-art .gloss-i{color:var(--ink2)}
:root[data-theme="dark"] .fhn-art .more-a,
:root[data-theme="dark"] .fhn-art .more-r{border-left-color:var(--line)}
:root[data-theme="dark"] .fhn-art .tbl th,
:root[data-theme="dark"] .fhn-art .tbl td,
:root[data-theme="dark"] .fhn-art .fig img{border-color:var(--line)}
:root[data-theme="dark"] .fhn-art .tbl tr:nth-child(even) td{background:var(--surface-2)}
:root[data-theme="dark"] .fhn-art .tbl tr.sum td{color:var(--accent)}
:root[data-theme="dark"] .fhn-art .tbl-n,
:root[data-theme="dark"] .fhn-art .foot,
:root[data-theme="dark"] .fhn-art .ovb-m{color:var(--muted)}

/* 窄屏：正文自带的 20px 内边距与两列数据卡在手机上太挤。
   选择器要带上 #single/#post —— 正文里那份内联 <style> 在文档里排在主题之后，
   同权重的话它赢，所以这里靠权重压过去（跟上面 .wrap 一个道理）。 */
@media (max-width:640px){
  #single{max-width:100%}
  #single .sBody .fhn-art .wrap,
  #single .sBody:not(:has(.fhn-art)){padding:20px 15px 34px;border-radius:14px}
  #single .sBody .fhn-art .ovb-grid,
  #post .pBody .fhn-art .ovb-grid{grid-template-columns:1fr}
  #single .sBody .fhn-art .ovb-v,
  #post .pBody .fhn-art .ovb-v{font-size:17.5px}
  #single .sBody .fhn-art p,
  #post .pBody .fhn-art p{text-indent:1.6em}
  /* 宽表格自己横滑，不要把页面撑破 */
  .fhn-art .tbl{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .fhn-art .tbl table{min-width:440px}
}

/* WP 标准评论 */
#cmtWrap{
  margin-top:clamp(34px,5vh,58px);padding-top:26px;border-top:1px solid var(--line);
}
#cmtWrap h2{
  font-family:var(--serif);font-size:20px;font-weight:600;margin-bottom:20px;
  display:flex;align-items:center;gap:10px;
}
#cmtWrap h2 .n{font-size:13px;color:var(--muted);font-family:inherit;font-weight:400}
#cmtWrap .comment-list{list-style:none;display:flex;flex-direction:column;gap:18px}
#cmtWrap .comment-list li{position:relative}
#cmtWrap .comment-list .children{margin:16px 0 0 42px;padding-left:14px;
  border-left:2px solid var(--line);display:flex;flex-direction:column;gap:16px;list-style:none}
#cmtWrap .comment-body{font-size:14px;line-height:1.9;color:var(--ink2)}
#cmtWrap .comment-author{display:flex;align-items:center;gap:10px;margin-bottom:6px}
#cmtWrap .comment-author img{width:32px;height:32px;border-radius:50%}
#cmtWrap .comment-author .fn{font-style:normal;font-weight:600;color:var(--ink);font-size:13.5px}
#cmtWrap .comment-meta{font-size:12px;color:var(--muted);margin-bottom:6px}
#cmtWrap .comment-meta a{color:var(--muted)}
#cmtWrap .reply a{display:inline-block;margin-top:6px;font-size:12px;color:var(--accent)}
#cmtWrap .comment-respond{margin-top:26px}
#cmtWrap .comment-reply-title{font-family:var(--serif);font-size:17px;font-weight:600;margin-bottom:14px;display:block}
#cmtWrap .comment-form{display:flex;flex-direction:column;gap:12px}
#cmtWrap .comment-form p{margin:0}
#cmtWrap .comment-form label{
  display:block;font-size:12.5px;color:var(--muted);margin-bottom:5px;
}
#cmtWrap .comment-form input[type="text"],
#cmtWrap .comment-form input[type="email"],
#cmtWrap .comment-form input[type="url"],
#cmtWrap .comment-form textarea{
  width:100%;font:inherit;font-size:14px;color:var(--ink);background:var(--surface);
  border:1px solid var(--line2);border-radius:10px;padding:10px 13px;outline:none;
  transition:border-color .2s,box-shadow .2s;
}
#cmtWrap .comment-form textarea{min-height:120px;resize:vertical;line-height:1.8}
#cmtWrap .comment-form input:focus,#cmtWrap .comment-form textarea:focus{
  border-color:color-mix(in srgb,var(--accent) 46%,var(--line2));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 10%,transparent);
}
#cmtWrap .comment-form .form-submit{margin-top:4px}
#cmtWrap .comment-form input[type="submit"]{
  height:38px;padding:0 22px;border-radius:999px;border:0;cursor:pointer;
  background:var(--accent);color:var(--on-accent);font:inherit;font-size:13.5px;
}
#cmtWrap .comment-form input[type="submit"]:hover{filter:brightness(1.08)}
#cmtWrap .comment-form .comment-notes,
#cmtWrap .comment-form .comment-form-cookies-consent label{font-size:12px;color:var(--muted)}
#cmtWrap .comment-form .comment-form-cookies-consent{display:flex;align-items:center;gap:8px}
#cmtWrap .comment-form .comment-form-cookies-consent input{width:auto}
#cmtWrap .comment-awaiting-moderation{font-size:12.5px;color:var(--warn)}
#cmtWrap .must-log-in{font-size:13px;color:var(--muted)}
#cmtWrap .comment-navigation{display:flex;justify-content:space-between;gap:14px;margin-top:18px;font-size:13px}
#cmtWrap .comment-navigation a{color:var(--accent)}
#cmtWrap .pingback .comment-body,#cmtWrap .trackback .comment-body{font-size:13px;color:var(--muted)}

/* ============================================================
   十四、窄屏
   ============================================================ */
@media (max-width:1100px){
  #path{width:min(288px,calc(100vw - 32px))}
}
@media (max-width:900px){
  #mvMap{height:clamp(320px,46vh,470px)}
  #mvLayers{width:200px}
}
@media (max-width:760px){
  /* ===== P1-2（2026-10-06）：手机档骨架收窄 =====
     原状：顶栏两行 110px（品牌行 + 全宽搜索框行），dock 两段约 200px
     （导航行 + 页脚信息两行），390×844 下内容可视区只剩 620px，占 73%。
     现在：顶栏单行 56px（搜索收成一枚放大镜，点开才展开）、dock 单行 56px、
     页脚五项信息整体撤出（已并入「关于我」浮层，见 footer.php）。
     合计 112px，内容可视区 788px。 */
  :root{--topH:56px}
  #topbar{grid-template-columns:auto 1fr auto;grid-template-rows:auto;row-gap:0;
    height:calc(var(--topH) + var(--safeT));padding-top:var(--safeT);padding-bottom:0}
  #brand{font-size:15.5px}
  #brand .mk{height:30px}
  #auth .btn{padding:0 10px}
  /* 手机档顶栏这一行只装得下三个图标：搜索 / 主题 / 关于我。
     登录与注册收进「关于我」浮层（footer.php 的 .fiAuth）。 */
  #auth > .btn{display:none}
  #aboutTog{display:inline-flex}
  #about .fiAuth a{min-height:44px;display:inline-flex;align-items:center;color:var(--ink2)}
  #about .fiAuth a:hover{color:var(--accent)}

  /* 搜索：默认收成图标按钮；点开后在顶栏下沿铺一条整宽输入条。
     #topbar 是 sticky（定位元素），所以这条绝对定位跟着它走，滚动时也不脱开。 */
  #qTog{display:inline-flex}
  #qWrap{
    position:absolute;left:0;right:0;top:calc(var(--topH) + var(--safeT));order:0;max-width:none;
    padding:8px 14px 10px;margin:0;
    background:color-mix(in srgb,var(--paper) 97%,transparent);
    backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    border-bottom:1px solid var(--line);
    box-shadow:0 20px 36px -32px rgba(var(--shade),.95);
    opacity:0;visibility:hidden;transform:translateY(-8px);
    transition:opacity .2s var(--ease),transform .2s var(--ease),visibility .2s;
  }
  body.qOpen #qWrap{opacity:1;visibility:visible;transform:none}
  #q{height:42px;font-size:16px}   /* 16px 起步：iOS 上小于 16px 的输入框会自动放大整页 */

  /* dock：单行 56px，导航横滑（三个入口在 390 宽下刚好，再窄也能滑） */
  #dockTop{flex-direction:row;align-items:center;gap:12px;
    padding:0 clamp(12px,3.2vw,20px);height:56px}
  #board{gap:16px;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  #board::-webkit-scrollbar{display:none}
  #board a{padding:6px 2px 10px;font-size:13.5px}
  /* 页脚五项信息在手机上对首访读者几乎零价值，却常驻两行 —— 整体撤出，
     微信号 / 关注 / 版权 / 备案号改在「关于我」浮层里给（那里本来就有微信）。 */
  #footWrap{display:none}
  #about .footIn{display:block}

  /* ===== P1-5：文章页头部两块 meta 压缩 =====
     原来面包屑四行 + 作者行一行约 180px，把摘要卡挤出首屏。
     现在面包屑压成单行横滑、作者行压成单行省略。 */
  .sHead .sMeta{font-size:12px;gap:9px;white-space:nowrap;overflow-x:auto;
    scrollbar-width:none;padding-bottom:2px}
  .sHead .sMeta::-webkit-scrollbar{display:none}
  #single .sBody .fhn-art .meta,
  #post .pBody .fhn-art .meta{
    display:block;white-space:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;
    -webkit-line-clamp:none;font-size:12px;margin:0 0 2px;padding-bottom:3px;
    scrollbar-width:none;
  }
  #single .sBody .fhn-art .meta::-webkit-scrollbar,
  #post .pBody .fhn-art .meta::-webkit-scrollbar{display:none}
  #single .sBody .fhn-art .byline,
  #post .pBody .fhn-art .byline{
    font-size:12px;line-height:1.6;margin:0 0 10px;padding-bottom:6px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  #single .sBody .fhn-art .wrap{padding-top:16px}

  /* ===== P1-3：地图 =====
     390 宽下地图只有 250-380px 高，141 个点位挤在上面基本点不中，
     图层面板也没有像样的入口 —— 地图的核心玩法（开图层→点位→该分类文章）
     在手机上等于没有。现在整块地图可以进全屏覆盖层，图层沉到底部抽屉，
     点位交互以「文字索引 + 地图」为主（索引就在地图下方，服务端渲染的那份）。 */
  #mvMap{height:clamp(250px,42vh,380px)}
  .mvTools{right:10px;top:10px}
  #mvFull{display:inline-flex}
  /* 图层面板在窄屏改为画框下方的常驻一栏，不再压在地图上 */
  #mvLayers{position:static;width:auto;margin:10px;top:auto;right:auto;
    background:var(--surface);backdrop-filter:none}
  .lyHead{padding:2px 6px 8px}
  .lyRow{padding:9px 7px}
  /* 点位的视觉命中区：手机上把点画大一圈，手指够得着
     （ECharts 的 scatter 只有 symbol 本身可点，没有独立的透明命中层） */
  body.mvFull{overflow:hidden}
  /* ⚠️ 关键：`#stage` 自己带 `position:relative;z-index:1`，会另开一个层叠上下文 ——
     光把 .mvStage 提到 z-index:56 也没用，它被关在 #stage 里，
     整体仍然排在顶栏(40)、底栏(39)下面，表现是「全屏了但顶栏还浮在地图上」。
     所以要把 #stage 这一层一起抬起来（仍低于 .mask 的 60，浮层照常盖住地图）。 */
  body.mvFull #stage{z-index:50}
  body.mvFull .mvStage{
    position:fixed;inset:0;z-index:56;margin:0;border:0;border-radius:0;
    display:flex;flex-direction:column;background:var(--paper);
    padding:calc(env(safe-area-inset-top) + 8px) 10px
            calc(env(safe-area-inset-bottom) + 8px);
    animation:fade .22s ease both;
  }
  body.mvFull #mvMap{flex:1 1 auto;height:auto;min-height:70dvh}
  body.mvFull .mvBar{padding:8px 4px}
  body.mvFull .mvBar .mvHint{display:none}      /* 全屏时收掉提示，腾出高度给抽屉 */
  /* 图层：底部抽屉。JS 会把 #mvLayers 临时搬进 .mvStage（它与 .mvStage 原本是兄弟，
     不搬进来的话会被固定定位的地图整个盖住，z-index 也救不回来）。 */
  body.mvFull #mvLayers{
    position:static;width:auto;margin:8px 0 0;max-height:34dvh;overflow-y:auto;
    flex:0 0 auto;border:1px solid var(--line);border-radius:14px;
    box-shadow:0 -18px 40px -34px rgba(var(--shade),.95);
  }
  body.mvFull .lyRow{min-height:44px}
  body.mvFull .mvTools button{width:40px;height:40px}

  #path{left:14px;right:14px;width:auto;max-height:38vh}
  /* 目录条目在手机上排两栏会挤成一团，收回单栏 */
  .hmChips{grid-template-columns:1fr}
  .hmChip{padding:12px 4px 12px 14px}
  .hmHero h1{font-size:clamp(26px,7vw,34px)}
  .qrCard .qrImg{width:152px;height:152px}
  #post .pHead{padding:22px 18px 14px}
  #post .pBody{padding:18px 18px 4px;font-size:14.5px}
  #post .cmt{padding:18px 18px 22px}
  .cmtList ol.children{margin-left:0}
  #cmtWrap .comment-list .children{margin-left:20px}

  /* 禁 JS 时的退路：放大镜点了不会展开，所以退回「搜索框常驻」的老形态
     （顶栏两行），功能不打折，只是又高回去。爬虫不点按钮，但真人可能禁用 JS。 */
  html.no-js{--topH:112px}
  html.no-js #qTog{display:none}
  html.no-js #aboutTog{display:none}
  html.no-js #auth > .btn{display:inline-flex}
  html.no-js #topbar{grid-template-columns:1fr auto;grid-template-rows:auto auto;
    row-gap:8px;height:calc(var(--topH) + var(--safeT));padding-bottom:8px}
  html.no-js #qWrap{
    position:static;grid-column:1/-1;opacity:1;visibility:visible;transform:none;
    background:none;border:0;box-shadow:none;backdrop-filter:none;
    -webkit-backdrop-filter:none;padding:0;
  }
  html.no-js #footWrap{display:block}
}

/* ============================================================
   十四、两个分栏页：最新发布 / 标签图谱
   ------------------------------------------------------------
   首页那两块只给「最近的一小口」，全量在各自的分栏页：
   最新发布 = 两列 + 页码 + 框架思维导图；标签图谱 = 共现网状图 + 页码。
   ============================================================ */

/* 区块标题行：标题在左、「更多」在右。首页两块与两个新页面共用。 */
.hmHead{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-bottom:16px}
.hmHead h2{margin-bottom:0}
.hmMore{
  font-size:12.5px;color:var(--accent);white-space:nowrap;
  transition:transform .24s var(--ease);
}
.hmMore:hover{transform:translateX(3px)}

/* 新页面的抬头 */
.pgHead{margin-bottom:clamp(20px,3vh,34px)}
.pgHead .eb{
  font-size:12px;letter-spacing:.28em;color:var(--muted);
  text-transform:uppercase;margin-bottom:12px;
}
.pgHead h1{font-family:var(--serif);font-size:clamp(26px,3vw,36px);font-weight:600;line-height:1.3}
.pgHead .lead{margin-top:12px;color:var(--ink2);font-size:14.5px;max-width:64ch;line-height:1.85}
.pgHead .lead a{
  color:var(--accent);
  border-bottom:1px solid color-mix(in srgb,var(--accent) 34%,transparent);
}

/* ---------------- 最新发布：两列 ---------------- */
.lxSec{margin-bottom:clamp(30px,5vh,54px)}
.lxGrid{display:grid;gap:13px;grid-template-columns:repeat(2,minmax(0,1fr))}
.lxCard{
  display:flex;flex-direction:column;gap:8px;
  background:var(--paper);border:1px solid var(--line);border-radius:14px;
  padding:15px 18px 15px 22px;
  box-shadow:inset 3px 0 0 var(--c,var(--accent));
  transition:border-color .2s,transform .3s var(--ease),background .3s;
  animation:fhnRise .55s var(--ease) both;
}
.lxCard:hover{border-color:transparent;transform:translateX(4px)}
.lxTop{display:flex;align-items:baseline;gap:12px;font-size:12px;color:var(--muted)}
.lxNo{
  font-style:normal;letter-spacing:.16em;font-weight:600;
  color:var(--c,var(--accent));font-variant-numeric:tabular-nums;
}
.lxDate{font-variant-numeric:tabular-nums}
.lxT{font-family:var(--serif);font-size:16.5px;font-weight:600;line-height:1.5}
.lxEx{
  font-size:13px;color:var(--muted);line-height:1.8;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.lxMeta{
  margin-top:auto;padding-top:9px;display:flex;gap:14px;flex-wrap:wrap;
  font-size:12px;color:var(--muted);
}

/* ---------------- 分页 ---------------- */
.pgWrap{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px;
  margin-top:26px;font-size:13px;
}
.pgNum,.pgBtn{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:36px;height:36px;padding:0 13px;border-radius:10px;
  border:1px solid var(--line);background:var(--paper);color:var(--ink2);
  transition:border-color .2s,color .2s,background .3s;
}
.pgNum{min-width:36px;padding:0;font-variant-numeric:tabular-nums}
.pgNum:hover,.pgBtn:hover{border-color:var(--accent);color:var(--accent)}
.pgNum.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.pgBtn.off{color:var(--muted);opacity:.5}
.pgGap{color:var(--muted);padding:0 3px}

/* ---------------- 图的操作条（思维导图 / 标签网状图共用） ----------------
   插在图的容器**外面**：容器是 overflow 容器，塞进去会跟着图一起横滑。 */
.figBar{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  margin-bottom:12px;font-size:12.5px;color:var(--muted);
}
.figB{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:33px;height:33px;padding:0 12px;border-radius:9px;
  border:1px solid var(--line);background:var(--paper);color:var(--ink2);
  font-size:13.5px;line-height:1;cursor:pointer;
  transition:border-color .2s,color .2s,background .3s,transform .18s var(--ease);
}
.figB:hover{border-color:var(--accent);color:var(--accent)}
.figB:active{transform:scale(.94)}
.figK{
  min-width:48px;text-align:center;font-size:12.5px;
  color:var(--ink2);font-variant-numeric:tabular-nums;
}
.figHint{font-size:12px;color:var(--muted)}

/* ---------------- 框架体系：思维导图（SVG 由 site.js 画） ---------------- */
.mmSec{margin-top:clamp(30px,5vh,54px)}
.mmSub{font-size:12px;color:var(--muted)}
.mmLead{font-size:13px;color:var(--muted);margin-bottom:16px}
.mmWrap{
  overflow-x:auto;-webkit-overflow-scrolling:touch;
  border:1px solid var(--line);border-radius:16px;background:var(--paper);padding:16px;
}

/* 两张图都能缩放 / 平移 / 拖，指针样式与选择行为放一起写。
   触摸端还有一条在 site.js 的 figMount 里：**空白处不接管手势** ——
   图上盖一层吃手势的区域，手机上手指一划页面就滚不动了。 */
.mmSvg,.tgSvg{
  display:block;height:auto;cursor:grab;
  -webkit-user-select:none;user-select:none;
}
.mmSvg.grabbing,.tgSvg.grabbing{cursor:grabbing}
.mmSvg text,.tgSvg text{font-family:inherit}
.mmSvg a,.tgSvg a{cursor:pointer}
.mmSvg .mmLk{stroke:var(--line2);fill:none;stroke-width:1.3}
.mmSvg .mmRoot{fill:var(--accent)}
.mmSvg .mmRootT{fill:var(--on-accent);font-size:14px;font-weight:600}
.mmSvg .mmRootS{fill:var(--on-accent);opacity:.72;font-size:10.5px}
.mmSvg .mmBx{fill:var(--surface);stroke:var(--line)}
.mmSvg .mmNo{fill:var(--muted);font-size:10px;letter-spacing:.1em;font-variant-numeric:tabular-nums}
.mmSvg .mmSmall{fill:var(--muted);font-size:10.5px;letter-spacing:.06em}
.mmSvg .mmBn{fill:var(--ink);font-size:13.5px;font-weight:600}
.mmSvg .mmSn{fill:var(--ink2);font-size:12.5px}
.mmSvg .mmCt{fill:var(--muted);font-size:11px;font-variant-numeric:tabular-nums}
.mmSvg a{transition:opacity .2s}
.mmSvg a:hover .mmBx{stroke:var(--accent)}
.mmSvg a:hover .mmBn,.mmSvg a:hover .mmSn{fill:var(--accent)}

/* 类别上的展开／收起钮。「−」是一条横线，「+」再加一条竖线，
   所以收起时多一个 path —— 不去动 circle 的圆心，图形就不会左右跳。 */
.mmSvg .mmTog{cursor:pointer}
.mmSvg .mmTog circle{
  fill:var(--surface);stroke:var(--line);stroke-width:1;
  transition:stroke .2s,fill .3s;
}
.mmSvg .mmTog path{
  fill:none;stroke:var(--ink2);stroke-width:1.7;stroke-linecap:round;
  transition:stroke .2s;
}
.mmSvg .mmTog:hover circle,.mmSvg .mmTog:focus-visible circle{
  stroke:var(--accent);fill:color-mix(in srgb,var(--accent) 9%,var(--surface));
}
.mmSvg .mmTog:hover path,.mmSvg .mmTog:focus-visible path{stroke:var(--accent)}
.mmSvg .mmTog:focus{outline:none}

/* ---------------- 标签图谱：共现网状图 ---------------- */
.tgSec{margin-bottom:clamp(30px,5vh,50px)}
.tgWrap{
  overflow-x:auto;-webkit-overflow-scrolling:touch;
  border:1px solid var(--line);border-radius:16px;background:var(--paper);padding:10px;
}
.tgSvg .tgEdges line{stroke:var(--accent);stroke-linecap:round}
/* 圆点自己设 touch-action:none：这是**唯一**要独占触摸手势的地方，
   不设的话在手机上拖圆点会被浏览器当成滚动页面，拖不动。 */
.tgNode circle{cursor:grab;touch-action:none}
.tgSvg.dragging .tgNode circle{cursor:grabbing}
.tgSvg .tgCt{
  fill:var(--surface);font-size:10px;font-weight:700;
  font-variant-numeric:tabular-nums;pointer-events:none;
}
.tgSvg .tgLb{
  fill:var(--ink2);font-size:12px;
  stroke:var(--paper);stroke-width:3.2;paint-order:stroke;
  transition:fill .2s;
}
.tgSvg a:hover .tgLb{fill:var(--accent)}
.tgSvg a:hover circle{stroke:var(--accent)}
.tgCap{font-size:12.5px;color:var(--muted);line-height:1.8;margin-top:12px;max-width:78ch}
.tgGrid{display:grid;gap:9px;grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
.tgChip{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 14px;border-radius:11px;
  background:var(--paper);border:1px solid var(--line);color:var(--ink2);font-size:13px;
  transition:border-color .2s,color .2s,transform .26s var(--ease),background .3s;
}
.tgChip:hover{
  border-color:transparent;color:var(--accent);transform:translateY(-2px);
  background:color-mix(in srgb,var(--accent) 6%,var(--paper));
}
.tgChip b{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tgChip i{flex:none;font-style:normal;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.tgChip:hover i{color:var(--accent)}

/* ---------------- 搜索：目录 / 正文 两组 ---------------- */
.srGrp{display:flex;flex-direction:column;gap:8px}
.srGrp + .srGrp{margin-top:26px}
.srH{
  display:flex;align-items:baseline;gap:10px;
  font-size:12px;letter-spacing:.2em;color:var(--muted);text-transform:uppercase;font-weight:600;
  margin-bottom:4px;
}
.srH b{font-size:15px;letter-spacing:0;color:var(--ink);font-variant-numeric:tabular-nums}
.srRow .rt{line-height:1.6}
.srSub{display:block;font-size:12.5px;color:var(--muted);line-height:1.8;margin-top:3px}
.srTip{font-size:13px;color:var(--muted);padding:6px 2px}
mark{
  background:color-mix(in srgb,var(--accent2) 26%,transparent);
  color:inherit;border-radius:3px;padding:0 2px;
}

@media (max-width:900px){
  .lxGrid{grid-template-columns:1fr}
}
@media (max-width:760px){
  .hmHead{margin-bottom:12px}
  .pgHead h1{font-size:clamp(23px,6.4vw,30px)}
  .lxCard{padding:13px 14px 13px 18px}
  .lxT{font-size:15.5px}
  .lxEx{-webkit-line-clamp:3}
  .pgNum,.pgBtn{min-width:32px;height:32px;font-size:12.5px;padding:0 10px}
  .pgNum{padding:0}
  .mmWrap,.tgWrap{padding:10px;border-radius:13px}
  .tgGrid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
  .srH{font-size:12px;letter-spacing:.16em}
  .figBar{gap:6px;margin-bottom:10px}
  .figB{min-width:30px;height:30px;padding:0 10px;font-size:12.5px}
  .figK{min-width:42px;font-size:12px}
  .figHint{font-size:12px}
}

/* ============================================================
   十五、整改附录（2026-10-01 需求书）
   ------------------------------------------------------------
   D2 小字 / D3 触控 / D5 安全区 / D6 无 JS 与减弱动效 / D7 面包屑
   D8 地图版面 / 服务端可爬内容（目录索引、地图点位清单）/ 404 页 / D4 打印
   ============================================================ */

/* ---------------- D5 全面屏安全区 ----------------
   viewport-fit=cover 之后 env() 才有值（header.php 已改）。
   顶栏与底栏都是 fixed，Home 横条会压上去。
   --topH / --footH 由 JS 量 offsetHeight 得来，加了内边距会自动包含进去，
   不用另外改算术。 */
:root{--safeT:env(safe-area-inset-top,0px);--safeB:env(safe-area-inset-bottom,0px)}
#topbar{padding-top:var(--safeT)}
#footWrap{padding-bottom:var(--safeB)}

/* ---------------- D6 无 JS / 减弱动效 ----------------
   卡片入场用的是 `animation:...both`，both 填充模式下「还没开始播」= opacity:0。
   没 JS（爬虫、禁 JS 的浏览器）或系统要求减弱动效时，内容必须老老实实可见。 */
.no-js .hmChip,.no-js .hmTag,.no-js .card,.no-js .row,.no-js .postRow,
.no-js .lxCard,.no-js .mvStage,.no-js .hmCard{
  animation:none!important;opacity:1!important;transform:none!important;
}
@media (prefers-reduced-motion:reduce){
  .hmChip,.hmTag,.card,.row,.postRow,.lxCard,.mvStage,.hmCard,.tgChip,.lxSec{
    animation:none!important;opacity:1!important;transform:none!important;
  }
}

/* ---------------- D2 正文里的数据卡与表注 ----------------
   这两条在正文自带的内联 <style> 里是 10.5px / 11px，而内联样式在文档里排在
   主题之后，**同权重它赢** —— 所以必须带上 #single / #post 这一级 ID 才压得住。 */
#single .sBody .fhn-art .ovb-m,#post .pBody .fhn-art .ovb-m{font-size:13px;line-height:1.65}
#single .sBody .fhn-art .tbl-n,#post .pBody .fhn-art .tbl-n{font-size:12px}

/* ---------------- D3 触控目标 ----------------
   WCAG 2.2 的下限是 24×24，正文流里的行内链接有豁免（补到 24 即可）；
   手机上再放大到 44 那一档。 */
#footBar .l > *,#footBar .r > *{min-height:24px;display:inline-flex;align-items:center}
.hmMore{min-height:28px;display:inline-flex;align-items:center;padding:2px 1px}
.hmTag{min-height:24px}
.lyRow{min-height:32px}
.tgChip{min-height:44px}
/* P2-9（2026-10-06 补做）：这个复选框实测被压成 19×24。
   原因不是没设尺寸 —— 是 flex 收缩：`.comment-form-cookies-consent` 是 flex 容器，
   勾选框默认 `flex-shrink:1`，旁边那行 label 一长就把它挤窄。
   加 `flex:none` 才是根治。（WCAG 2.2 的 24×24 是下限，
   实际命中区是「勾选框 + 旁边那行字」整行，所以 24 够。） */
#cmtWrap .comment-form-cookies-consent input[type=checkbox],
.comment-form-cookies-consent input[type=checkbox]{width:24px;height:24px;flex:none}
#cmtWrap .comment-form .comment-form-cookies-consent label{min-height:24px;
  display:inline-flex;align-items:center}
.sTags a,.inlTag{padding-top:3px;padding-bottom:3px}
@media (max-width:760px){
  #footBar .l > *,#footBar .r > *{min-height:44px}
  .hmMore{min-height:44px}
  .hmTag{min-height:32px}
  .pgNum,.pgBtn{min-width:44px;height:44px;padding:0 12px}
  .pgNum{padding:0}
  .lyRow{min-height:44px}
  #qClear{width:44px;height:44px}
}

/* ---------------- D7 面包屑（正文里那行 .meta） ----------------
   分隔符与编号是**文章内容**里的字，已在库里统一成「› 」（见整改记录）；
   这里只管手机端最多两行，超了省略。 */
#single .sBody .fhn-art .meta,#post .pBody .fhn-art .meta{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}

/* ---------------- D8 地图版面 ----------------
   图层面板原来绝对定位压在地图右上角，正好盖住黑龙江、吉林，
   图层名也被挤成「国家骨干冷链物…」。改成地图右侧独立一列，
   窄屏自动落到地图下方（此时文案里的「右侧」也跟着换成「下方」）。 */
#viewMap .mvCol{max-width:1180px}
.mvGrid{display:grid;grid-template-columns:minmax(0,1fr) 236px;gap:14px;align-items:start}
#mvLayers{position:static;width:auto;background:var(--surface);
  backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:none}
.lyRow .nm{white-space:normal;overflow:visible;text-overflow:clip}
.mvCap{font-size:12px;color:var(--muted-ink)}
.mvMob{display:none}
@media (max-width:900px){
  .mvGrid{grid-template-columns:1fr}
  #mvLayers{margin:0}
  .mvDesk{display:none}
  .mvMob{display:inline}
}

/* ---------------- 服务端可爬内容：目录索引 ----------------
   分类树与地图点位清单，都是 PHP 直接输出的真链接（inc/data.php）。
   对人是一份「全站目录」，对没有 JS 的爬虫是通往各层的路。 */
.idxBox{
  margin-top:clamp(26px,4vh,44px);border:1px solid var(--line);border-radius:16px;
  background:var(--paper-up);padding:0 16px;
}
.idxBox > summary{
  padding:14px 2px;cursor:pointer;display:flex;flex-wrap:wrap;gap:4px 12px;
  align-items:baseline;list-style:none;
}
.idxBox > summary::-webkit-details-marker{display:none}
.idxBox > summary::after{content:"▾";margin-left:auto;color:var(--muted);transition:transform .24s var(--ease)}
.idxBox[open] > summary::after{transform:rotate(180deg)}
.idxBox > summary b{font-size:14px;color:var(--ink)}
.idxBox > summary span{font-size:12px;color:var(--muted)}
.idxCols{columns:3;column-gap:26px;padding:4px 0 18px}
.idxCols-map{columns:2}
.idxGrp{break-inside:avoid;margin-bottom:16px}
.idxGrp h3{font-size:13px;margin-bottom:6px;display:flex;flex-wrap:wrap;gap:4px 8px;align-items:baseline}
.idxGrp h3 a{color:var(--ink);border-bottom:1px solid var(--line2)}
.idxGrp h3 a:hover{color:var(--accent);border-color:var(--accent)}
.idxGrp h3 em{font-style:normal;font-size:12px;color:var(--muted)}
.idxL{list-style:none;margin:0;padding-left:10px;border-left:1px solid var(--line)}
.idxL li{margin:2px 0;font-size:12.5px;line-height:1.75;color:var(--ink2)}
.idxL a{color:var(--ink2)}
.idxL a:hover{color:var(--accent)}
.idxL i{font-style:normal;font-size:12px;color:var(--muted);margin-left:5px}
.idxProv{font-size:12.5px;line-height:1.9;color:var(--ink2);margin:0 0 5px;text-indent:0}
.idxProv b{color:var(--ink);margin-right:6px}
.idxProv a{color:var(--ink2);border-bottom:1px solid transparent}
.idxProv a:hover{color:var(--accent);border-color:var(--accent)}
@media (max-width:900px){.idxCols,.idxCols-map{columns:2}}
@media (max-width:640px){.idxCols,.idxCols-map{columns:1}}

/* ---------------- 404 页 ---------------- */
.nfWrap{max-width:820px;margin:0 auto}
.nfLead{margin-top:12px;color:var(--ink2);font-size:15px;line-height:1.9}
.nfSearch{display:flex;gap:10px;margin:22px 0}
.nfSearch input{
  flex:1;min-width:0;padding:11px 14px;border:1px solid var(--line);border-radius:12px;
  background:var(--surface);color:var(--ink);font-size:14px;
}
.nfSearch button{
  padding:11px 20px;border-radius:12px;background:var(--accent);color:var(--on-accent);
  font-size:14px;white-space:nowrap;
}
.nfNav{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:26px}
.nfNav a{
  min-height:36px;display:inline-flex;align-items:center;padding:0 15px;
  border:1px solid var(--line);border-radius:999px;font-size:13.5px;color:var(--ink2);
  transition:border-color .2s,color .2s;
}
.nfNav a:hover{border-color:var(--accent);color:var(--accent)}
.nfRecent h2{font-size:14px;letter-spacing:.1em;color:var(--muted);margin-bottom:10px}
.nfBack{margin:26px 0 10px}

/* ---------------- D4 打印 / 导出 PDF ----------------
   原来是「一页都没有」：滚动容器 position:fixed + overflow:auto，
   打印引擎只拿得到可视区那一屏，七千多像素的长文打成 1 页。
   这里把外壳摊平成普通文档流，并去掉导航、深色底与所有动画。 */
@page{margin:16mm 14mm}
@media print{
  #topbar,#footWrap,#dock,#path,.mvTools,.figBar,.flow,.idxBox{display:none!important}
  html,body{background:#fff!important;color:#000!important;overflow:visible!important;height:auto!important}
  #stage{
    position:static!important;inset:auto!important;overflow:visible!important;
    height:auto!important;max-height:none!important;padding:0!important;display:block!important;
  }
  #home,#viewTree,#viewMap,#single,#feed{max-width:100%!important;width:auto!important}
  #stage.reading{margin-right:0!important}
  #post.panel,.mask{position:static!important;display:block!important;background:none!important}
  #post.panel .box{width:auto!important;border:0!important;box-shadow:none!important;height:auto!important;padding:0!important}
  .hmChip,.hmTag,.card,.row,.postRow,.lxCard,.mvStage,.hmCard{
    animation:none!important;opacity:1!important;transform:none!important;
  }
  .hmEntry,.hmChips,.hmList,.figBar,.mmWrap,.tgWrap{border-color:#bbb!important}
  /* 正文里的链接把地址摆出来，纸面上也能回原文 */
  #single .sBody a[href]:not(.kwt):not(.inlTag):after,
  #single .sPrev a[href]:after,
  .sRecList a[href]:after{content:" (" attr(href) ")";font-size:12px;color:#555}
  a[href^="#"]:after{content:""}
}

/* ---------------- D3 续：目录索引与页脚可点元素的命中高度 ----------------
   索引里的链接是纯文字（12.5px），行框只有 22px 高，手机上点不准。
   inline-block + min-height 把它撑到 24（手机 32），视觉上只是行距松了一点。 */
.idxGrp h3 a,.idxL a,.idxProv a{display:inline-block;min-height:24px;line-height:1.9}
.idxL li{margin:0}
#footBar .footQr > .lbl,#footBar button,#footBar a{min-height:24px;display:inline-flex;align-items:center}
#footBar .l>span,#footBar .r>span{display:inline-flex;align-items:center}
#single .sMeta a,#single .sPrev a{display:inline-flex;min-height:24px;align-items:center}
@media (max-width:760px){
  .idxGrp h3 a,.idxL a,.idxProv a{min-height:32px}
  #footBar .footQr > .lbl,#footBar button,#footBar a{min-height:44px}
  #single .sPrev a,#single .sMeta a{min-height:44px}
}
