/*! 元生泰官网 · 唯一样式表（单文件、零外部 CSS/JS）依据：架构设计 §5 / PRD §8
   分区：令牌→重置→布局→页头导航→面包屑→页脚→组件→工具类→响应式→偏好

   ── 视觉重设计（2026-10-04，依据 docs/视觉设计规格_参考站采集.md + 四个设计 skill）──
   · 客户裁定 Q-A：**深棕黑主导 + 品牌红点缀**。原墨绿 #1F3D34 退场，改用实测自
     寿仙谷的深棕黑 #241D1B / #2F2725 系；品牌红 #C90E10 面积 ≤10%，只作强调。
   · 客户裁定 Q-B：**克制引入宣纸古籍风** —— 纸色底 + 衬线标题 + 双线框，不加纹理图（零带宽）。
   · 客户裁定 Q-C：轮播**保持手动**（无自动播放）。
   · 参考站实测共同点：真正主导版面的是深色中性 + 大比例灰阶，红仅点缀 —— 这才是
     「简约大气而不促销」的成因，故本表**中性色占比刻意做大**。
   · 配色族收敛为 4 个（品牌红 / 墨族 / 暖砂 / 功能色），原信息蓝、苔绿、浅绿底一律
     并入暖砂族与墨族；旧令牌名保留为**兼容别名**，避免模板侧漏改。
   · 零依赖：无 CDN / 无 webfont / 无 @import，字族仅系统栈；派生 hex 在前、oklch 在
     @supports 内覆盖，老浏览器不掉色。
   · **布局类属性（display / grid-template / flex 方向 / 宽度 / 断点数值）一律未动**，
     本次只改颜色、字体、边框、圆角、阴影与间距取值。
*/
/* 1. 令牌 */
:root{
  /* ① 品牌族 · PRD §8.2（色相沿用原值 #C90E10，仅派生） */
  --c-brand:#C90E10;          /* 品牌标准色，强调用，面积≤10%（5.91:1 / 白） */
  --c-brand-dark:#9E0A0C;     /* 派生·深一档：hover 与小字（8.39:1 / 白） */
  --c-brand-soft:#FAE7E4;     /* 派生·浅一档：底色面（禁作正文文字色） */
  --c-brand-on-dark:#E8453F;  /* 派生·亮一档：**仅用于深底上的状态指示**
                                 实测品牌红 #C90E10 在深棕黑 #241D1B 上只有 2.81:1，
                                 低于非文本对比度 3:1 底线（WCAG 1.4.11），故亮化为 4.61:1 */
  /* ② 墨族 · 版面主色（页头/页脚底、标题）· 取自寿仙谷实测 #2F2725 */
  --c-ink-strong:#241D1B;     /* 深棕黑：页头 / 页脚 / 主标题（16.58:1 / 白） */
  --c-ink:#332A27;            /* 正文深墨（12.63:1 / 纸底） */
  --c-ink-2:#6E625C;          /* 次级文字·暖灰（5.89:1 / 白，5.32:1 / 纸） */
  --c-line:#E4DACB;           /* 分隔线·暖砂灰 */
  --c-surface:#FFFFFF;        /* 面·白（卡片/表格底） */
  --c-surface-2:#F7F3EA;      /* 面·宣纸白（页面底/区块底） */
  /* ③ 暖砂族 · 古籍风辅助色，仅作装饰线与底色面 */
  --c-warm:#D9C4A3;           /* 暖砂（1.70:1 / 白 —— 禁止用作文字色） */
  --c-wood:#7A5C3A;           /* 木色（6.14:1 / 白，5.55:1 / 纸 —— 可作文字与链接） */
  /* ④ 功能色（非配色族；法定标识与状态专用，禁装饰） */
  --c-compliance:#B3261E;     /* 合规红：法定标识 / 待填 */
  --c-success:#2E7D46;        /* 成功绿：状态 */
  /* 兼容别名：旧令牌名 → 新族，模板侧无需改动 */
  --c-ink-green:var(--c-ink-strong);  /* 原墨绿主导色 → 深棕黑 */
  --c-moss:var(--c-wood);             /* 原苔绿 → 木色 */
  --c-info:var(--c-wood);             /* 原信息蓝 → 木色（配色族由 5 收为 4） */
  --c-green-soft:var(--c-surface-2);  /* 原浅绿底 → 纸色底 */
  /* 字体（字族 ≤2：无衬线正文 + 衬线标题/史料；禁 Inter/Roboto/Fraunces 等外部字） */
  --font-sans:system-ui,-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",
    "Source Han Sans SC","Noto Sans CJK SC",sans-serif;
  --font-serif:"Source Han Serif SC","Noto Serif SC","Songti SC",STSong,SimSun,serif;
  /* 兼容别名（旧令牌名，逐步替换用） */
  --f-body:var(--font-sans);
  --f-title:var(--font-serif);
  /* 字号 / 行高阶梯（中文行高 ≥1.6；标题用 clamp 流体字号） */
  --fs-h1:clamp(28px,4vw,44px);   --lh-h1:1.3;
  --fs-h2:clamp(22px,2.6vw,30px); --lh-h2:1.4;
  --fs-h3:20px;                   --lh-h3:1.5;
  --fs-body:17px;                 --lh-body:1.8;
  --fs-sm:14px;                   --lh-sm:22px;
  --fs-note:13px;                 --lh-note:20px;
  /* 间距 · 8pt 网格（--space-1…--space-8 = 4/8/12/16/24/32/48/64） */
  --space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;
  --space-5:24px;--space-6:32px;--space-7:48px;--space-8:64px;
  /* 圆角 / 阴影 / 尺度 */
  --radius:3px;--radius-lg:6px;
  --shadow-1:0 1px 3px rgba(36,29,27,.10);
  --shadow-2:0 8px 20px rgba(36,29,27,.12);
  --container:1200px;--gutter:24px;--touch:44px;--maxw-read:34em;
}
/* 派生色 oklch 覆盖（先 hex 后 oklch，老浏览器自动回退到上面的 hex）
   以下 oklch 值均由 sRGB→OKLab 精确换算得出，非估写 */
@supports (color:oklch(50% 0.1 30)){
  :root{
    --c-brand-dark:oklch(44.32% 0.1760 28.2);
    --c-brand-soft:oklch(94.23% 0.0212 28.3);
    --c-brand-on-dark:oklch(62.55% 0.2008 26.9);
    --c-line:oklch(89.23% 0.0230 78.2);
    --c-surface-2:oklch(96.48% 0.0127 86.8);
    --c-warm:oklch(82.95% 0.0502 79.1);
    --c-wood:oklch(49.75% 0.0627 69.0);
    --c-ink-2:oklch(50.57% 0.0181 48.3);
  }
}
/* 2. 重置与排版 */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--c-surface-2);color:var(--c-ink);font-family:var(--font-sans);
  font-size:var(--fs-body);line-height:var(--lh-body);font-variant-numeric:tabular-nums;
  /* 2026-10-12：通栏色带用 `width:100vw` 外扩，100vw 含滚动条 ⇒ 会多出约 8px
     横向溢出。用 `clip` 而非 `hidden`：**clip 不建立滚动容器**，故顶栏的
     `position:sticky` 仍以视口为基准，不会失效（`hidden` 会失效）。 */
  overflow-x:clip}
h1,h2,h3,h4{font-family:var(--font-serif);color:var(--c-ink-strong);margin:0 0 .5em;font-weight:700;
  letter-spacing:.01em}
h1{font-size:var(--fs-h1);line-height:var(--lh-h1)}
h2{font-size:var(--fs-h2);line-height:var(--lh-h2)}
h3{font-size:var(--fs-h3);line-height:var(--lh-h3);font-weight:600}
p{margin:0 0 1em}
a{color:var(--c-info);text-decoration:none}
a:hover,a:focus{text-decoration:underline;color:var(--c-brand-dark)}
img{max-width:100%;height:auto;display:block}
ul,ol{margin:0;padding:0;list-style:none}
table{border-collapse:collapse;width:100%}
/* 键盘焦点：全局品牌红描边（白底 5.91:1）；深底页头/页脚另用纸色以保证可见（16:1） */
:focus-visible{outline:2px solid var(--c-brand);outline-offset:2px}
.site-header :focus-visible,.site-footer :focus-visible{outline-color:var(--c-surface-2)}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--c-brand);color:#fff;padding:.6em 1em;z-index:100}
.skip-link:focus{left:var(--space-2);top:var(--space-2)}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* 3. 布局 */
.container{max-width:var(--container);margin:0 auto;padding:0 var(--gutter);width:100%}
.main{padding-top:28px;padding-bottom:56px}
.sec{margin:0 0 40px}
/* 小节标题：品牌红短竖线 + 衬线字（借鉴寿仙谷「深色字 + 一点红」），线宽由 5px 收敛到 3px */
.sec-title{border-left:3px solid var(--c-brand);padding-left:var(--space-3)}
.page-h1{margin-bottom:.4em}
.updated{color:var(--c-ink-2);font-size:var(--fs-sm);margin:0 0 20px}
.updated time{font-variant-numeric:tabular-nums}
.sec-body{max-width:var(--maxw-read)}
/* 滚动浮现动画（客户反馈第三轮第 1 项）。
   ⚠️ 两个易错点：
   ① `.reveal` 类名**只由 JS 添加**（见 site.js 的 initReveal）——JS 未加载 /
      关闭动效时元素根本没有这个类，内容照常可见。**绝不把 opacity:0 写在
      HTML 会直接命中的选择器上**，否则 JS 一挂整页就白了。
   ② **transition 只写在 `.is-in` 上，不写在 `.reveal` 上**：若写在 `.reveal`，
      JS 加类的那一帧会触发一次「1 → 0」的淡出（用户看到内容先闪一下再消失），
      入位时又淡入。写在 `.is-in` 上则「隐藏瞬时、显现才过渡」，符合预期。 */
.reveal{opacity:0;transform:translateY(18px)}
.reveal.is-in{opacity:1;transform:none;
  transition:opacity .45s ease-out,transform .45s ease-out;
  transition-delay:var(--rd,0ms)}
@media (prefers-reduced-motion:reduce){
  /* 兜底：即便类已加上（例如运行中改了系统偏好），也立刻恢复可见 */
  .reveal{opacity:1;transform:none;transition:none}
}
/* 锚点跳转平滑滚动（含「返回顶部」）。放在 no-preference 内，关闭动效时自动退回瞬时跳转 */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
/* 4. 页头 / 导航（深棕黑底 + 品牌红细线收口） */
.site-header{background:var(--c-ink-strong);color:#fff;position:sticky;top:0;z-index:50;
  box-shadow:var(--shadow-1);border-bottom:2px solid var(--c-brand-on-dark)}
.header-inner{display:flex;align-items:center;gap:20px;min-height:var(--space-8)}
.brand{color:#fff;display:flex;align-items:center}
.logo-svg{color:#fff;display:block}
.main-nav{margin-left:auto}
.nav-list{display:flex;flex-wrap:wrap;gap:var(--space-1)}
.nav-item{position:relative}
.nav-item>a{display:flex;align-items:center;min-height:var(--touch);padding:0 var(--space-3);color:#fff;font-weight:500}
.nav-item>a.on{box-shadow:inset 0 -2px 0 var(--c-brand-on-dark)}
.nav-item>a:hover{color:#fff;text-decoration:none;background:rgba(255,255,255,.08)}
.submenu{display:none;position:absolute;left:0;top:100%;min-width:170px;background:var(--c-surface);border:1px solid var(--c-line);box-shadow:var(--shadow-2);border-radius:var(--radius);padding:6px 0;border-top:2px solid var(--c-brand)}
.submenu li a{display:block;padding:9px var(--space-4);color:var(--c-ink);min-height:var(--touch)}
.submenu li a:hover,.submenu li a.on{background:var(--c-surface-2);color:var(--c-brand-dark);text-decoration:none}
.nav-item:hover .submenu,.nav-item:focus-within .submenu{display:block}
.header-cta{margin-left:auto;display:flex;align-items:center;gap:10px}
.header-cta .tel{color:#fff;font-size:var(--fs-sm);white-space:nowrap}
.nav-toggle{display:none;min-height:var(--touch);padding:0 14px;border:1px solid rgba(255,255,255,.5);background:transparent;color:#fff;border-radius:var(--radius);cursor:pointer}
/* 5. 面包屑 */
.breadcrumb{margin:var(--space-4) 0 var(--space-1)}
.breadcrumb-list{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:var(--fs-sm);color:var(--c-ink-2)}
.breadcrumb-list a{display:inline-flex;align-items:center;min-height:var(--touch)}
.breadcrumb-list [aria-current]{color:var(--c-ink)}
/* 6. 页脚（两家主体并列 + 通用信息 + 页脚导航；非广告位、无法定标识）
   暖灰字全部为暖砂灰，与深棕黑底同族。
   ⚠️ 2026-10-04 修正：原 `.ft-inner{padding:36px 0 28px}` 把 `.container` 的左右
   24px 内边距覆盖成 0，导致整个页脚**顶格贴到视口边缘**（客户反馈第 9、10 项）。
   现只设纵向内边距，横向沿用 `.container` 的 gutter。 */
.site-footer{background:var(--c-ink-strong);color:#EDE6DC;margin-top:var(--space-5)}
.ft-inner{padding-top:36px;padding-bottom:28px;border-top:3px solid var(--c-brand)}
/* 页脚导航：改用 flex 让每栏按内容取宽，栏间距均匀 —— 原来 grid 的 1fr 会把
   5 栏摊满整行，栏内文字短、栏间留白过大（客户反馈第 9 项）。 */
.footer-nav{display:flex;flex-wrap:wrap;gap:22px 40px;padding-bottom:var(--space-5)}
.ft-col{flex:0 1 auto}
.ft-col-h{font-size:var(--fs-body);margin:0 0 10px;color:#fff}
.ft-col-h a,.ft-col ul a,.ft-orgs a{color:#E0D6C8}
/* 页脚链接不拆行：「工商查询」曾被从「工/商查询」中间断开 */
.ft-orgs a{white-space:nowrap}
.ft-col ul li{margin:6px 0;font-size:var(--fs-sm)}
.ft-col-h a:hover,.ft-col ul a:hover,.ft-orgs a:hover{color:#fff}
/* 信息栏：两家主体**并列**，各自带一条顶部细线（对称，不靠左边框造不一致的缩进）；
   左侧边距由 `.container` 的 gutter 提供，不顶格（客户反馈第 10、11 项）。 */
.ft-orgs{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px;padding-top:22px;font-size:var(--fs-sm);line-height:1.9}
.ft-a,.ft-b,.ft-c{border-top:1px solid rgba(255,255,255,.16);padding-top:14px}
.ft-orgs p{margin:0 0 var(--space-1)}
.ft-org{font-size:var(--fs-body);font-weight:700;color:#fff}
/* A 组版权行：与 B 组的 ICP 备案号构成第三行，两块行数对称（客户反馈第三轮第 4 项） */
.ft-copy{color:#E0D6C8}
/* 最底部法定警示条：黑底白字整幅通栏。
   置于 `.container` 之外（见 layout.footer），故宽度＝视口宽，无需 100vw。 */
.ft-legal{background:#000;color:#fff;text-align:center;padding:11px var(--gutter)}
.ft-legal p{margin:0;font-size:var(--fs-sm);line-height:1.6}
/* 7. 组件 */
.fact-table{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);margin:0 0 var(--space-2)}
.fact-table th,.fact-table td{padding:11px 14px;text-align:left;vertical-align:top;border-bottom:1px solid var(--c-line)}
.fact-table tr:last-child th,.fact-table tr:last-child td{border-bottom:0}
.fact-table th{width:34%;background:var(--c-surface-2);font-weight:600;color:var(--c-ink-strong)}
.fact-table tr:nth-child(even) td{background:#FCFAF5}
.fact-table--3 th{width:26%}
.ft-src{color:var(--c-ink-2);font-size:var(--fs-note)}
.pending{color:var(--c-compliance);font-weight:600;border-bottom:1px dashed var(--c-compliance);cursor:help}
.cert-status{display:inline-block;font-size:var(--fs-note);padding:2px var(--space-2);border-radius:999px;background:var(--c-line);color:var(--c-ink-2)}
.cert-card{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);padding:18px;margin:0 0 18px}
.cert-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.cert-name{margin:0}
/* 证书图框：双线（函套感）——古籍风的克制做法，不加纹理图 */
.cert-fig{margin:var(--space-3) 0;border:3px double var(--c-line);border-radius:var(--radius);overflow:hidden}
/* —— 卡片高度统一（2026-10-12 美术测试，挂在 `.cert-grid--plate` 下，仅资质页）——
   问题实测（1440px / 4 列）：整卡高 252~622px，同行极差最大 177px。方差来源三处：
     ① 图版 130~317px（证书原件横版 A4 与竖版 A4 混排，宽高比 0.71~1.41）；
     ② 标题 30~114px（证书全称长短不一，换行 1~4 行）；
     ③ 字段区 0~200px（A/B 栏 5 行字段，D 栏无字段）。
   三层解法（全部纯 CSS、无 JS、不裁切证书）：
     ① **图版归一** —— 图占固定的 4:3 版心 + `object-fit:contain`，原件完整可见，
        留白处用「宣纸白」承托，观感即博物馆的**裱贴版**（这是成熟站点处理
        「不同尺寸图片混排」的通法：不裁图、不拉伸，只统一**容器**）；
     ② **同行等高** —— `align-items` 由 `start` 改回 grid 默认的 `stretch`，
        同行卡片底边齐平；短卡多出的空间留在卡片底部，不产生错位；
     ③ **子网格** —— `grid-template-rows: subgrid` 让同行卡片的「图版 / 标题 /
        字段 / 专利行 / 备注行」**逐段对齐**（不只底边齐，内部每一行都齐）。
        这是 CSS Grid Level 2 的正解，@supports 兜底，老浏览器退回 ②。 */
.cert-grid--plate{align-items:stretch;
  /* 回纹单元（**一笔连环型／雷纹**）：一条线横竖折绕成向心回旋的方形螺旋，
     即「回」字的回转形，民间称「富贵不断头」。路径：外框 → 底边回折 →
     内圈再折绕两道，每道间距 3（描边 1.2 ⇒ 留白约 1.8），末端开口即螺旋的「口」。
     ★ 用 **SVG 遮罩**而不是直接给 SVG 描色：data URI 内部的颜色**无法继承
     CSS 变量**，写死就与 `--c-wood` 脱钩；mask 只取 alpha，颜色交给
     `background:var(--c-wood)`，故回纹色与章回体序号**永久同源**。
     ★ `preserveAspectRatio='none'` 让单元精确填满 `mask-size`，不出现letterbox。 */
  --fret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 11' preserveAspectRatio='none'%3E%3Cpath d='M1 10V1H15V10H4V4H12V7H8' fill='none' stroke='%23000' stroke-width='1.2'/%3E%3C/svg%3E")}
.cert-grid--plate .cert-fig img{width:100%;height:auto;aspect-ratio:4/3;
  object-fit:contain;background:var(--c-surface-2)}
/* 标题至少预留 2 行：单行标题的卡片不会比多行标题矮一整行（60px = 2 × 20px × 1.5）。 */
.cert-grid--plate .cert-name{min-height:calc(2 * var(--lh-h3) * 1em)}

/* 卡片序号**独占一行**（2026-10-13 客户裁定）。
   `.cert-head` 是 `display:flex; flex-wrap:wrap`，序号（`::before`）与 `<h3>` 同为其
   flex 项 —— 短名字（如「全市先进基层党组织」8 字）会与序号挤在同一行，而长名字
   自动换行到下一行，于是同一板块内卡片名起始位置不齐。给序号 `flex:0 0 100%`
   令其**永远占满一行**，名字一律从下一行左边缘起排。
   作用域仅 `.cert-grid--plate`（本页独有的按页开关）⇒ /chandi/ 的 `.cert-grid` 不受影响。 */
.cert-grid--plate .cert-head::before{flex:0 0 100%}

/* ── 超一行板块 → **一行横向滚动**（2026-10-13 客户裁定）────────────────────
   触发：卡片数 ≥ `_SCROLL_MIN`(5)。1152px 内容宽下证书网格 4 列，5 张即换行。

   为什么是「可滚动」而不是「自动滚动播放」：
     * 无缝自动轮播**必须复制一份内容**才能首尾相接 —— 那会把这批证书在 DOM 里
       写两遍，与客户「保证 AI 可读」的前提直接冲突（重复内容同样稀释检索信号）；
     * 纯 CSS 自动位移做不到"停下可读"以外的可控性（WCAG 2.2.2 要求可暂停）。
   ⇒ 采用**原生横向滚动 + 滚动吸附**：全部卡片仍在 DOM 中、无 JS、可键盘操作。

   页边距：容器仍在 `.container` → `.sec-body--wide` 内，**左边界与其它内容对齐**，
   只有右侧允许滚出。窄屏降列，≤719px 回到正常换行（手机上再叠一层横向滚动
   会与页面纵向滚动打架）。 */
.cert-grid.cert-grid--scroll,.patent-grid.patent-grid--scroll{
  /* ⚠️ 本条有两处坑，缺一不可：
     ① **必须显式清掉基础规则的 auto-fill 显式轨道**（`.cert-grid` / `.patent-grid`
        在文件**更后面**，未清则它仍圈出 N 条显式列，auto-fill 的余数留下一条
        几十像素的残轨，最后一张卡被压成 50px 宽 —— 实测踩到）；
     ② **选择器写成双类名**（`.cert-grid.cert-grid--scroll`）：基础规则在文件
        末尾，同优先级下"后写的赢"，单类名会被 `grid-template-columns` 反盖。
        双类名把优先级提到 0,2,0，与文件顺序无关。
     ③ **列宽用定长，不要包 minmax(0, X)**：`minmax(0,X)` 是"可伸缩轨道"，
        容器放不下时它会**缩到刚好塞下**（实测 264→208，于是 5 张又挤进一行、
        滚动失效）。定长才是"放不下就溢出、溢出即可滚"。 */
  grid-template-columns:none;
  grid-auto-flow:column;
  grid-auto-columns:calc((100% - 3 * var(--space-4)) / 4);
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  padding-bottom:var(--space-3)}          /* 给滚动条留位，免压卡片边框 */
.cert-grid.cert-grid--scroll>*,.patent-grid.patent-grid--scroll>*{scroll-snap-align:start}
.cert-grid.cert-grid--scroll:focus-visible,.patent-grid.patent-grid--scroll:focus-visible{
  outline:2px solid var(--c-brand);outline-offset:4px}
@media (max-width:1000px){
  .cert-grid.cert-grid--scroll,.patent-grid.patent-grid--scroll{
    grid-auto-columns:calc((100% - var(--space-4)) / 2)}
}
@media (max-width:719px){
  .cert-grid.cert-grid--scroll,.patent-grid.patent-grid--scroll{
    grid-auto-flow:row;grid-template-columns:1fr;
    overflow-x:visible;padding-bottom:0}
}
/* —— 回纹窗框（2026-10-12 客户二次裁定，同样只挂在 `.cert-grid--plate` 下）——
   卡片边框由「1px 暖砂灰」改为**传统方形回纹窗框**，色随章回体序号取 `--c-wood`
   （6.14:1，文字级令牌；`--c-warm` 1.70:1 禁作前景色）。三层结构：
     ① **外框** —— 1px 木色，直角（`border-radius:0`，窗框不倒圆角）；
     ② **回纹带** —— 上下各一条二方连续回纹（`--fret` SVG 遮罩，见上）。
     就这两层，**不设内框**（曾加过，与回纹打架，见下方规则注释）。
   ⚠️ v1 用 `repeating-linear-gradient` 打等距竖齿 —— **被客户否**：那只有竖线
      没有横折，观感是「刻度尺」。回纹的定义是「横竖短线**折绕**组成的**回旋状**
      纹样」，必须有横向回折才成立（资料：回纹形如「回」字，俗名「富贵不断头」，
      分方回单体型／减笔组合型／正反 S 型／一笔连环型四类，此处取一笔连环型）。
   ⚠️ 两个伪元素都是 `position:absolute` —— 卡片在子网格下是 **grid 容器**，
      在流内的伪元素会被当成网格项塞进某一行，撑坏逐段对齐；绝对定位则
      脱离网格布局，不参与行分配。`pointer-events:none` 保证不挡卡片内链接。 */
.cert-grid--plate .cert-card{position:relative;border:1px solid var(--c-wood);
  border-radius:0;padding:32px 24px}
/* —— 卡片内部节奏（2026-10-12 客户反馈：内容多的卡片文字贴回纹太近）——
   · **版心上下 32px**：回纹带占 y 5~17，故文字与纹样之间实留 15px 净空，
     标题再长、备注再多也不会「咬」到纹样；左右 24px（那两侧没有纹样，
     只需与外框保持呼吸）。
   · **块间距统一 14px**：原来 `.cert-fig` 是 12px 上下、`.cert-fields/
     .cert-patent/.cert-note` 各是 10px 上 —— 子网格下**外边距不合并**
     （grid item 的 margin 不会 collapse，相邻块的实际间距是两者之和），
     于是「图→字段」成了 22px、「字段→备注」只有 10px，疏密不一。
     现在先 `> *{margin:0}` 全部清零，再由 `* + *` 统一给 14px：
     首块无上边距、末块无下边距，边上的距离全交给 padding，
     卡片内部读起来是一整块，而不是几段拼起来的。
   · **内细框已删除**：原本内缩 20px 的细线距回纹带（止于 17px）只有 3px，
     两根线互相干扰，看上去像回纹「多了一道」。删掉后只剩外框 + 回纹两层。 */
.cert-grid--plate .cert-card > *{margin:0}
.cert-grid--plate .cert-card > * + *{margin-top:14px}
/* ② 回纹带：上下各一条**二方连续**回纹（回纹最典型的用法就是锁边／边饰）。
      两层 mask 同图、不同 `mask-position`，`repeat-x` 沿横向循环。
      只做上下、不做左右 —— 四边都做会在四角撞出两个挤在一起的回纹单元
      （`repeat-x/repeat-y` 会朝两个方向平铺，无法只在角外起始），留白反而干净。 */
.cert-grid--plate .cert-card::after{content:"";position:absolute;inset:0;
  pointer-events:none;background:var(--c-wood);opacity:.85;
  -webkit-mask-image:var(--fret),var(--fret);
          mask-image:var(--fret),var(--fret);
  -webkit-mask-position:0 5px,0 calc(100% - 17px);
          mask-position:0 5px,0 calc(100% - 17px);
  -webkit-mask-size:18px 12px,18px 12px;
          mask-size:18px 12px,18px 12px;
  -webkit-mask-repeat:repeat-x,repeat-x;
          mask-repeat:repeat-x,repeat-x}
/* ③ 子网格的**启用块写在下面**（`.cert-grid` 之后）—— `.cert-grid{gap:…}` 与本规则
   同特异性，若写在其前面，父级 16px 行间距会反过来覆盖这里的 `row-gap:0`
   并渗进卡片内部各段之间（实测题顶由 213px 被顶到 230px）。CSS 顺序即优先级，别挪回去。 */
.cert-fig figcaption{padding:6px 10px;font-size:var(--fs-note);color:var(--c-ink-2);background:var(--c-surface-2)}
.cert-fields{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;margin:10px 0 0;font-size:var(--fs-sm)}
/* `dt` 用 `nowrap` 锁住标签列宽，避免窄卡片下「证书名称」被逐字竖排；
   `dd` 加 `min-width:0` 才能让 `1fr` 真正收缩，`overflow-wrap:anywhere`
   防止 `R2016275DDH1162501` 这类无空格长编号撑破卡片。 */
.cert-fields dt{color:var(--c-ink-2);white-space:nowrap}
.cert-fields dd{margin:0;min-width:0;overflow-wrap:anywhere}
.cert-patent{margin:10px 0 0;font-size:var(--fs-sm);color:var(--c-ink-2)}
/* 公开备注（2026-10-10）：只承载「某项信息待企业提供」这类**可公开的缺口说明**，
   与内部校核备注（`certs.py` 的 `note` 键）严格分开 —— 后者含「PRD S-03」「6.7」
   等内部编号，**绝不可上页**。样式沿用 `.cert-patent` 的次级文字层级，
   再加一条左侧竖线，让「这是待补缺口、不是证书内容」一眼可辨。 */
.cert-note{margin:10px 0 0;padding-left:10px;border-left:2px solid var(--c-warm);
  font-size:var(--fs-sm);line-height:var(--lh-sm);color:var(--c-ink-2)}
/* 相关认证：一行四张（客户 2026-10-07）。
   演进：一张一行竖排（页面过长）→ 3 列。但 3 列时该板块仍走 `.sec-body`
   （`--maxw-read:34em` ≈544px）的**窄容器**，卡片被压在左侧、右侧空出，
   「证书名称」窄到逐字竖排。故本页改用**宽容器**（模板 `wide=bool(d.get("certs_grid"))`，
   `.sec-body--wide{max-width:100%}`），列数交给 auto-fill 自适应：
   1152px 可用宽度（1200 − 2×24 gutter）下恰为 **4 列**（每列 276px）；
   视口收窄时依次降为 3 / 2 / 1 列，左右边距始终相等。
   ⚠️ `250px` 是校准值：5 列需要 5×250+4×16=1314px > 1152px，故最大就是 4 列。
   仅 /chandi/ 使用（模板按页开关 `.cert-grid`）；资质与荣誉页 / 质量与检测页不受影响。 */
.cert-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));
  gap:var(--space-4);align-items:start}
/* `.cert-card` 自带 `margin:0 0 18px`，在网格里会造成卡内留白不均；
   只在 `.cert-grid` 内清零，**不改 `.cert-card` 本身**。 */
.cert-grid .cert-card{margin:0}
/* 证书档案号（2026-10-07 内容排列试点）：网格内按 DOM 顺序自动编 01…07。
   取自获奖站的「档案目录」手法 —— 并列的同质条目给出**可见的序号**，读者一眼
   知道「共几件、到第几件」，也把三份**同名**的地理标志证书（三家主体持有）
   从视觉上区分开（原先是三张外观完全相同的卡，扫读时像重复内容）。
   **纯 CSS 计数器实现**：零模板改动、零内容改动，`cert_card` 在资质页 /
   质量与检测页的渲染逐字节不变。 */
/* 证书档案号（2026-10-07 客户裁定：**推广到全站**）。
   按**栏**独立编号（`.cert-grid` / `.cert-col` / `.sec-body` 各自从 01 起）——
   资质页 A/B 两栏是**并列**看的，若整页连续编号，同一行的左右两张卡会差几十号，
   反而更难读。`.cert-card:not(.honor-card)` 用于排除 C 企业荣誉 / D 产学研：
   `honor_card` 与 `cert_card` **共用 `.cert-card`**，仅凭容器分不开（C/D 与 A/B
   同在 `.cert-cols > .cert-col` 内），故在其 `class` 上追加 `honor-card` 作钩子。
   **纯 CSS 计数器**：零内容改动；编号走伪元素、不进 DOM 文本 ⇒ **对 GEO 零影响**。 */
.cert-grid,.cert-col,.sec-body{counter-reset:cert-no}
/* ③ **子网格（对齐卡片内部各段）** —— 必须写在 `.cert-grid{gap:…}` 之后，
   否则父级 16px 行间距会覆盖这里的 `row-gap:0` 并渗进卡片内部（实测：题顶被顶高 17px）。
   父网格给出 5 段隐式行（图版 / 标题 / 字段 / 专利行 / 备注行），每张卡 `span 5`
   并子网格化 ⇒ **同行五段逐段对齐**，缺某段的卡留空轨（不会错位）。
   卡片间距改由 `margin-bottom` 提供；列间距不受影响。
   `@supports` 兜底：不支持子网格的浏览器退回「图版归一 + 同行等高」，不塌。 */
@supports (grid-template-rows:subgrid){
  .cert-grid--plate{grid-auto-rows:auto auto auto auto auto;row-gap:0}
  .cert-grid--plate .cert-card{grid-row:span 5;display:grid;grid-template-rows:subgrid;
    margin:0 0 var(--space-4)}
  .cert-grid--plate .cert-card > .cert-fig{grid-row:1}
  .cert-grid--plate .cert-card > .cert-head{grid-row:2}
  .cert-grid--plate .cert-card > .cert-fields{grid-row:3}
  .cert-grid--plate .cert-card > .cert-patent{grid-row:4}
  .cert-grid--plate .cert-card > .cert-note{grid-row:5}
}
.cert-card:not(.honor-card){counter-increment:cert-no}
.cert-card:not(.honor-card) .cert-head::before{
  content:counter(cert-no,decimal-leading-zero);
  font-family:var(--font-serif);font-size:var(--fs-sm);font-weight:400;
  color:var(--c-warm);letter-spacing:.06em;line-height:1}
/* 网格内证书缩略图可点开原图（同尺寸原文件）；链接撑满图框。 */
.cert-fig-link{display:block;position:relative}
/* 「查看原件」指示（2026-10-07 内容排列试点）：可点的证据图必须**看得出可点**。
   原先缩略图只有 hover 光标变化 —— 触屏与键盘用户无从感知，等于把入口藏起来。
   改为**常显**角标（不依赖 hover），并用 `pointer-events:none` 保证不挡点击。
   仅 `.cert-grid` 内（`link_to_image=True`）才渲染该链接，其它证书区不受影响。 */
.cert-fig-link::after{content:"查看原件 ↗";position:absolute;right:8px;bottom:8px;
  font-size:var(--fs-note);line-height:1;padding:5px 9px;border-radius:999px;
  background:rgba(36,29,27,.78);color:#fff;pointer-events:none;
  opacity:0;transition:opacity .18s ease}
/* 指针设备：hover / 键盘聚焦时才浮现 —— 证书图是**证据**，默认不该被任何浮层压住
   （实测常显角标会盖住证书右下角的签发印章）。 */
.cert-fig-link:hover::after,.cert-fig-link:focus-visible::after{opacity:1}
/* 无指针设备（触屏）：没有 hover 可依赖，常显，否则这个入口等于不存在。 */
@media (hover:none){.cert-fig-link::after{opacity:1}}
@media (prefers-reduced-motion:reduce){.cert-fig-link::after{transition:none}}
/* 卡片 hover：只改 border-color / box-shadow / 底色，禁止位移与缩放 */
/* 数字卡：去卡片化，改为「品牌红顶线 + 衬线大数」，与仙芝楼「数值在上、标签在下」一致 */
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:var(--space-4)}
.stat-card{background:transparent;border:0;border-top:2px solid var(--c-brand);border-radius:0;padding:var(--space-4) 0 0;display:flex;flex-direction:column;gap:var(--space-1)}
.stat-card:hover{border-top-color:var(--c-brand-dark)}
.stat-num{font-family:var(--font-serif);font-size:36px;font-weight:700;color:var(--c-ink-strong);line-height:1.1}
.stat-caliber{font-size:var(--fs-sm);color:var(--c-ink-2)}
/* 品牌沿革（客户反馈第七轮：**两栏** —— 轴线置于页面正中）
   左栏＝时间轴（轴线落在左栏右边界＝容器中线），事件文字在轴**左侧**；
   右栏＝企业理念，`position:sticky` 吸附跟随滚动。
   时间轴为**倒序**：顶部「至今」，越往下越久远。
   动画（参考视频站历史记录的时间轴观感）：
     · 竖线随时间轴滚入视口**逐渐点亮**（.timeline-progress 高度由 JS 按滚动设置）；
     · 节点圆点**未到达时是暖砂色、被扫过后变品牌红**（.tl-item--passed）；
     · 条目自右侧轻微滑入（.tl-item.reveal 用 translateX），逐条 --rd 错峰。 */
.tl-layout{display:grid;grid-template-columns:1fr 1fr}
.tl-col-left{min-width:0}
.tl-col-right{min-width:0}
.tl-philosophy{position:sticky;top:84px;padding-left:var(--space-6)}
/* 「企业理念」现为 h2（GEO：与三张理念卡 h3 拉开层级）——但**视觉必须仍是 h3 的大小**。
   全局 `h2{line-height:var(--lh-h2)}` 与 `h3{font-weight:600}` 都是元素选择器，
   `.tl-phil-h`（0,1,0）虽压得住 font-size，却压不住这两条，故在此显式写回：
   line-height 用 --lh-h3（1.5）、font-weight 用 600，保证换标签后几何零变化。 */
.tl-phil-h{font-size:var(--fs-h3);line-height:var(--lh-h3);font-weight:600;
  margin:0 0 var(--space-3)}
/* 右栏理念卡：**单列纵向堆叠**（`.phil-grid` 本身是自适应网格，故此处必须提高
   特异性 —— `.phil-grid--side` 与 `.phil-grid` 同为 0,1,0，写在前面会被后面盖掉） */
.tl-philosophy .phil-grid{grid-template-columns:1fr;gap:var(--space-3)}
.timeline-wrap{position:relative}
.timeline{position:relative;margin:0;padding:0}
/* 静态轴线（暖灰）与进度线（品牌红）同位于左栏右边界＝容器中线 */
.timeline::before{content:"";position:absolute;right:0;top:6px;bottom:6px;width:2px;background:var(--c-line)}
.timeline-progress{position:absolute;right:0;top:6px;width:2px;height:0;background:var(--c-brand);
  transition:height .15s linear}
.tl-item{position:relative;margin:0 0 30px;padding-right:16px;
  display:grid;grid-template-columns:minmax(0,1fr);justify-items:end;row-gap:6px}
/* 条目正文占满整行（网格默认按内容收缩，须显式拉伸） */
.tl-body{justify-self:stretch;min-width:0}
/* 圆点压在轴线上：轴 2px 位于 [w-2, w]，12px 圆点居中于轴 → right:-5px */
.tl-item::before{content:"";position:absolute;right:-5px;top:5px;width:12px;height:12px;border-radius:50%;
  background:var(--c-warm);border:2px solid var(--c-surface-2);transition:background .25s ease}
.tl-item--passed::before{background:var(--c-brand)}
/* 顶部「至今」节点：日期点放大、深色实心，视觉上作为时间轴的起点锚（优先级高于 --passed） */
.tl-item--current::before{width:16px;height:16px;right:-7px;top:3px;background:var(--c-ink-strong)}
.tl-item--current .tl-date{font-size:var(--fs-sm);color:var(--c-surface);background:var(--c-ink-strong)}
.tl-item--current .tl-date::after{border-right-color:var(--c-ink-strong)}
.tl-item--current .tl-event{font-family:var(--font-serif);font-size:var(--fs-h3);color:var(--c-ink-strong)}
/* 滚动浮现（覆盖通用 .reveal 的下移）：**只让年份胶囊滑入**。
   条目本体不再位移 —— 否则圆点会随条目一起离开时间轴轴线（客户 2026-10-07 反馈）。 */
.tl-item.reveal{opacity:1;transform:none}
.tl-item.reveal .tl-date{transform:translateX(-22px)}
.tl-item.reveal.is-in .tl-date{transform:none;
  transition:transform .45s cubic-bezier(.22,.61,.36,1);transition-delay:var(--rd,0ms)}
@media (prefers-reduced-motion:reduce){
  /* 兜底：即便类已加上，也让胶囊立刻归位（与通用 .reveal 的兜底同源） */
  .tl-item.reveal .tl-date{transform:none;transition:none}
}
/* 年份 → **品牌红胶囊**，右对齐贴住轴线（客户 2026-10-07：原为左上角小字、离轴线一整栏）。
   年份标签是 **h3**（GEO：与「品牌沿革」h2 拉开层级）——全局
   `h1,h2,h3,h4{margin:0 0 .5em;letter-spacing:.01em}` 与 `h3{line-height:var(--lh-h3)}`
   都是元素选择器，`.tl-date`（0,1,0）虽压得住 font-size / color / font-weight / font-family，
   却压不住这三条，故在此显式写回。 */
.tl-date{position:relative;display:block;justify-self:end;white-space:nowrap;
  font-family:var(--font-sans);font-size:var(--fs-note);font-weight:600;letter-spacing:.02em;
  color:#fff;background:var(--c-brand);border-radius:4px;padding:3px 9px;margin:0;line-height:1.4}
/* 胶囊靠轴线一侧的箭头突起：指向轴上的圆点；动画结束后尖端与圆点相切。
   几何：`.tl-item` padding-right 16px（胶囊右缘距轴 16px）→ 三角长 7px 时尖端落在
   距轴 9px 处＝圆点（12px 内容圈，居中于轴）的左缘。改 padding-right 须同比改 right。 */
.tl-date::after{content:"";position:absolute;right:-7px;top:50%;transform:translateY(-50%);
  width:0;height:0;border-style:solid;border-width:5px 7px 5px 0;
  border-color:transparent var(--c-brand) transparent transparent}
/* 同一年份下的多个条目：细虚线分隔 */
.tl-entry+.tl-entry{margin-top:14px;padding-top:14px;border-top:1px dashed var(--c-line)}
.tl-event{margin:2px 0}
.tl-src{font-size:var(--fs-note);color:var(--c-ink-2)}
/* 条目配图：统一尺寸的缩略图排（不等比缩放，用 contain 避免裁掉奖状文字） */
.tl-figs{display:flex;flex-wrap:wrap;gap:10px;margin:10px 0 0;justify-content:flex-end}
.tl-fig{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  width:240px;height:196px;margin:0;padding:6px;background:var(--c-surface);
  border:1px solid var(--c-line);border-radius:var(--radius)}
.tl-fig:hover{border-color:var(--c-brand)}
.tl-fig img{max-width:100%;max-height:100%;width:auto;height:auto}
.tl-fig-link{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
/* 占位槽（节目画面待企业提供）：与 .tl-fig 等高，虚线区分「尚未有图」 */
.tl-ph{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  width:240px;height:196px;background:var(--c-surface-2);
  border:2px dashed var(--c-line);border-radius:var(--radius)}
.tl-ph span{font-size:var(--fs-note);color:var(--c-ink-2)}
.tl-meta{margin:8px 0 0;font-size:var(--fs-note);color:var(--c-ink-2)}
.tl-link{color:var(--c-wood)}
.tl-link:hover{color:var(--c-brand-dark)}
/* 返回顶部浮动按钮：默认隐藏，由 JS 滚动超过一屏后加 .is-visible。
   visibility:hidden 同时保证隐藏时不可 Tab 聚焦（显示状态与焦点可达性一致）。 */
.to-top-wrap{margin:28px 0 0}
.to-top{position:fixed;right:24px;bottom:28px;z-index:60;display:inline-flex;align-items:center;gap:6px;
  padding:10px 16px;background:var(--c-ink-strong);color:#fff;border-radius:var(--radius);
  font-size:var(--fs-sm);box-shadow:var(--shadow-2);text-decoration:none;
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .2s ease}
.to-top:hover{color:#fff;text-decoration:none;background:var(--c-brand)}
.to-top.is-visible{opacity:1;visibility:visible;pointer-events:auto}
.to-top-icon{font-size:1.1em;line-height:1}
@media (max-width:767px){.tl-fig,.tl-ph{width:168px;height:140px}.to-top{right:14px;bottom:14px;padding:9px 13px}}
.faq-list{margin:0}
.faq-q{font-weight:700;color:var(--c-ink-strong);margin:18px 0 6px;padding-left:18px;position:relative}
.faq-q::before{content:"问";position:absolute;left:0;color:var(--c-brand);font-size:var(--fs-sm)}
.faq-a{margin:0;padding-left:18px;position:relative}
.faq-a::before{content:"答";position:absolute;left:0;color:var(--c-wood);font-size:var(--fs-sm)}
.faq-src{display:block;margin-top:6px;font-size:var(--fs-note);color:var(--c-ink-2)}
.card{display:flex;gap:var(--space-4);background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);padding:14px;margin:0 0 14px}
.card:hover{border-color:var(--c-wood)}
.card-fig{flex:0 0 220px;max-width:220px}
.card-fig img{border-radius:var(--radius)}
.card-title{margin:0 0 6px;font-size:var(--fs-h3)}
.card-sum{color:var(--c-ink-2);margin:0 0 6px}
.card-upd .updated{margin:0}
.outlet{display:flex;gap:var(--space-4);background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);padding:14px;margin:0 0 14px}
.outlet:hover{border-color:var(--c-wood)}
.outlet-fig{flex:0 0 200px;max-width:200px;display:flex;align-items:center;justify-content:center;background:var(--c-surface-2);border-radius:var(--radius);min-height:120px}
.outlet-name{margin:0 0 6px;font-size:var(--fs-h3);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.outlet-type{font-size:var(--fs-note);font-weight:500;color:var(--c-wood);border:1px solid var(--c-wood);border-radius:999px;padding:1px var(--space-2)}
.outlet-info p{margin:0 0 var(--space-1);font-size:var(--fs-sm)}
.outlet-map{color:var(--c-info)}
.purchase{background:var(--c-surface);border:1px solid var(--c-line);border-left:3px solid var(--c-ink-2);border-radius:var(--radius);padding:var(--space-4) 18px;margin:28px 0 0}
.purchase-note{margin:0 0 var(--space-2);font-size:var(--fs-note);color:var(--c-ink-2)}
.purchase-text{margin:0;font-weight:600}
.purchase-links{display:flex;flex-wrap:wrap;gap:var(--space-3);margin:0 0 var(--space-3)}
.purchase-links a{display:inline-flex;align-items:center;min-height:var(--touch)}
.purchase-qr{display:flex;align-items:center;gap:var(--space-3);margin-top:10px}
.legal-badge{background:var(--c-surface);border:2px solid var(--c-compliance);border-radius:var(--radius);padding:var(--space-4) 18px;margin:0 0 28px}
.legal-badge p{margin:0 0 6px}
.lb-warn{display:flex;align-items:center;gap:10px;color:var(--c-compliance);font-weight:700;font-size:var(--fs-h3)}
.lb-warn .bh-icon{flex:0 0 auto}
.lb-pop,.lb-no{font-size:var(--fs-sm)}
.lb-no{color:var(--c-ink-2)}
.note{border-radius:var(--radius);padding:var(--space-3) var(--space-4);margin:0 0 20px;font-size:var(--fs-sm);border-left:3px solid var(--c-wood);background:rgba(122,92,58,.07)}
.note--warn{border-left-color:var(--c-compliance);background:var(--c-brand-soft)}
.related{margin:36px 0 0;padding-top:20px;border-top:1px solid var(--c-line)}
.related-h{font-size:var(--fs-h3);margin-bottom:10px}
.related ul{display:flex;flex-wrap:wrap;gap:10px}
.related a{display:inline-flex;align-items:center;min-height:var(--touch);padding:0 14px;border:1px solid var(--c-line);border-radius:999px;background:var(--c-surface)}
.related a:hover{border-color:var(--c-brand);color:var(--c-brand-dark);box-shadow:var(--shadow-1)}
.ph-empty{border:2px dashed var(--c-line);border-radius:var(--radius);padding:40px 20px;text-align:center;color:var(--c-ink-2);margin:var(--space-5) 0}
.ph-label{font-size:var(--fs-h3);color:var(--c-ink-2);margin:0 0 var(--space-2)}
.ph-note{margin:0;font-size:var(--fs-sm)}
/* 8. 工具类 */
.text-mid{color:var(--c-ink-2)}.mt-0{margin-top:0}.mb-0{margin-bottom:0}
/* 8b. 页面模板（T03）：主图 / 入口卡 / 图网格 / 双栏 / 列表 */
.hero{margin:0 0 20px;border-radius:var(--radius-lg);overflow:hidden;border:3px double var(--c-line)}
.hero img{width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}
.hero-cap{padding:var(--space-2) var(--space-3);font-size:var(--fs-note);color:var(--c-ink-2);background:var(--c-surface-2)}
.entry-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--space-4)}
.entry-card{background:var(--c-surface);border:1px solid var(--c-line);border-top:2px solid var(--c-line);border-radius:var(--radius);padding:var(--space-4) 18px}
.entry-card:hover{border-top-color:var(--c-brand);box-shadow:var(--shadow-1)}
.entry-title{margin:0 0 6px;font-size:var(--fs-h3)}
.entry-title a{color:var(--c-ink-strong)}
.entry-title a:hover{color:var(--c-brand-dark)}
.entry-note{margin:0;color:var(--c-ink-2);font-size:var(--fs-sm)}
/* ── 保健食品「两条产品线」（2026-10-12 Round T）────────────────────────────
   这一组页面的真实用途：**访客拿着手里的盒子来核对包装与批准文号**。
   故版面按这个用途排，而不是按「栏目页应有的样子」排：
   · 栏目页 `.sblock` —— 一条产品线一整幅，图占 58%、文占 42%。只有两条线、
     且各有实拍，所以不需要等权入口卡网格（那是条目多、无图时的解法）；
   · 系列页 `.vrow` —— 一规格一整行，同样是左图右字段，条目之间只用一条
     暖砂细线分隔（列表感，不是卡片网格，卡片会把注意力从图上挪走）；
   · **批准文号从字段表里提出来，独立成行**（`.vrow-approval`）：
     它是这一页唯一必须逐字比对的字符串，给它最高的视觉权重 ——
     结构即信息，剩下的包装/规格/注册人才走 `dl` 同权排列。
   不新增任何颜色：只用既有令牌（--c-surface/-2、--c-line、--c-wood、--c-ink-*），
   hover 只改颜色不做位移（与全站卡片 hover 口径一致）。 */
.sblocks{display:flex;flex-direction:column;gap:var(--space-6)}
.sblock{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius)}
/* ⚠️ 列宽用 `fr` 不用百分比：`58% 42%` 之和已是 100%，再加 `gap` 会溢出容器
   （fr 会先扣掉 gap 再分配剩余空间）。`minmax(0,…)` 防内容把列撑破。 */
.sblock-link{display:grid;grid-template-columns:minmax(0,58fr) minmax(0,42fr);
  align-items:stretch;color:inherit;text-decoration:none}
.sblock-fig{background:var(--c-surface-2);padding:var(--space-4);
  display:flex;align-items:center;justify-content:center}
.sblock-fig img{width:100%;height:auto;aspect-ratio:3/2;object-fit:contain}
.sblock-body{padding:var(--space-6) var(--space-5);display:flex;flex-direction:column;
  justify-content:center;gap:var(--space-2)}
.sblock-name{margin:0;font-family:var(--f-title);font-size:var(--fs-h2);
  line-height:var(--lh-h2);color:var(--c-ink-strong)}
.sblock-blurb{margin:0;color:var(--c-ink);font-size:var(--fs-body);line-height:var(--lh-body)}
.sblock-go{margin-top:var(--space-1);color:var(--c-wood);font-size:var(--fs-sm)}
.sblock-link:hover .sblock-name,.sblock-link:focus-visible .sblock-name,
.sblock-link:hover .sblock-go,.sblock-link:focus-visible .sblock-go{color:var(--c-brand-dark)}
.sblock-link:hover,.sblock-link:focus-visible{text-decoration:none}
/* 系列页：一规格一整行 */
.vrows-intro{max-width:var(--maxw-read);margin:0 0 var(--space-4);
  color:var(--c-ink-2);font-size:var(--fs-sm);line-height:var(--lh-sm)}
.vrows{display:flex;flex-direction:column}
.vrow{display:grid;grid-template-columns:minmax(0,58fr) minmax(0,42fr);
  gap:var(--space-5);padding:var(--space-5) 0;border-top:1px solid var(--c-line)}
.vrow:last-child{border-bottom:1px solid var(--c-line)}
.vrow-figs{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3);align-content:start}
.vrow-figs .fig{margin:0;border:1px solid var(--c-line)}
/* 图版归一：源图横竖混杂，放任 height:auto 同排会一高一矮；
   统一 3/4 裱贴（留白不裁切，裁切会切掉包装上的字） */
.vrow-figs img{width:100%;height:auto;aspect-ratio:3/4;object-fit:contain;
  background:var(--c-surface-2)}
.vrow-figs figcaption{padding:var(--space-1) var(--space-2);text-align:center;
  background:var(--c-surface)}
.vrow-body{min-width:0}
.vrow-name{margin:0 0 var(--space-2);font-family:var(--f-title);font-size:var(--fs-h3);
  line-height:var(--lh-h3);color:var(--c-ink-strong)}
.vrow-approval{margin:0 0 var(--space-3);padding-left:var(--space-3);
  border-left:2px solid var(--c-wood)}
.vrow-alabel{display:block;color:var(--c-ink-2);font-size:var(--fs-note);
  line-height:var(--lh-note)}
.vrow-aval{display:block;color:var(--c-wood);font-size:var(--fs-body);
  font-variant-numeric:tabular-nums;letter-spacing:.02em}
.vrow-fields{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;margin:0;
  font-size:var(--fs-sm)}
.vrow-fields dt{color:var(--c-ink-2);white-space:nowrap}
.vrow-fields dd{margin:0;min-width:0;overflow-wrap:anywhere}
.vrow-note{margin:var(--space-2) 0 0;font-size:var(--fs-note);line-height:var(--lh-note);
  color:var(--c-ink-2)}
.vrow-channels{margin:var(--space-3) 0 0;display:flex;flex-wrap:wrap;
  gap:var(--space-2) var(--space-4);font-size:var(--fs-sm)}
.vrow-link{color:var(--c-wood)}
.vrow-link.is-text{color:var(--c-ink-2)}
/* <860px：整幅图文改上下堆叠（图在上、字段在下，仍保持「图先于字」） */
@media (max-width:859px){
  .sblock-link{grid-template-columns:1fr}
  .sblock-body{padding:var(--space-5) var(--space-4)}
  .vrow{grid-template-columns:1fr;gap:var(--space-4)}
}
/* ── 栏目主导页「脉络」版式（2026-10-07，本地站 /wuyilingzhi/ 专用）─────────────
   自检发现的具体问题（改版前后对比截图见 _qa/wylz_redesign/）：
   ① 四个入口＝四张等权圆角卡，被 `.sec-body`（--maxw-read:34em≈578px）压在 1200px
      容器左半幅，右侧整半幅空着 —— 版面读起来像「没排完」；
   ② 卡片是通用模板脸：同圆角、同边框、同阴影，四张之间没有任何关系表达；
   ③ 「最后更新」单独占一行、导语套在灰框提示块里，层级被切碎。
   改法：这四个条目在本行业里是一条**真实的次序**（道地 → 工艺 → 质检 → 认证），
   故改由**一条横向脉络**承载：暖砂 1px 细线贯穿整幅（尾端 12% 渐隐，避免被右边界切断），
   四个「站点」（圆环节点 + 衬线标题 + 说明）挂在线上，整条链通栏（1152px）。
   · 进入某站（hover / 键盘聚焦）：节点由「白心暖砂环」点亮为品牌红实心 + 4px 淡红光晕，
     标题转品牌深红并浮出下划线；只改颜色与描边，**不做位移与缩放**
     （与全站卡片 hover 口径一致，见 `.cert-card` 上方注释）。
   · 一次编排好的入场：脉络线自左画出（.7s），四个节点沿线错峰点亮 —— 全页唯一非交互动效。
   · <860px：同一条脉络**转为竖向**（见「9. 响应式」区的 859px 断点），隐喻不变。
   · 减动效偏好：显式关掉入场动画，直接落回「线已画完、节点已点亮」的静态终态
     （节点只是装饰，正文文本全程不曾被动画隐藏）。
   ⚠️ 只有 `/wuyilingzhi/` 走本套类名（模板 `tpl_hub` 独用）；其余列表页仍走
   `.entry-grid` / `.entry-card`，行为与外观零变化。 */
.hub-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--space-2) var(--space-5);flex-wrap:wrap;margin:0 0 var(--space-4)}
.hub-head .page-h1{margin:0}
.hub-head .updated{margin:0}
/* 导语：去掉灰框提示块，改用衬线正文（32em ≈ 640px）——本页的字体锚点 */
.hub-deck{font-family:var(--font-serif);font-size:var(--fs-h3);line-height:1.85;color:var(--c-ink);
  max-width:32em;margin:0 0 var(--space-7)}
/* 导语**之上**的小字说明（客户 2026-10-07）：**与子页面补充说明 `.hub-note` 同字号**
   （`--fs-sm`）。承载「本栏目汇总…」这类**点名四个子栏目**的定义性陈述 —— 保留在最前
   以维持页面的自我定义，但不再撑起视觉重量，让位给下方新的三段品牌叙述。 */
.hub-deck-note{font-size:var(--fs-sm);line-height:var(--lh-sm);color:var(--c-ink-2);
  max-width:32em;margin:0 0 var(--space-3)}
/* 多段导语：`.hub-deck` 内可含多个 `<p>`（字符串列表时输出），段间留 `space-4`、末段不留。 */
.hub-deck p{margin:0 0 var(--space-4)}
.hub-deck p:last-child{margin-bottom:0}
/* 客户 2026-10-07 要求「**无边框紧密排列**」：四张配图**无缝拼接**成一整条画册式通栏，
   列间距由 32px 收到 0（图本来就没有边框，故只需改间距）。
   文字若也贴到 0 会挤在一起，故由 `.hub-text` 自己出内边距拉开。 */
.hub-chain{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:0}
.hub-chain::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,var(--c-warm) 0,var(--c-warm) 88%,rgba(217,196,163,0) 100%)}
.hub-stop{position:relative;padding-top:var(--space-6)}
.hub-stop::before{content:"";position:absolute;top:-4px;left:0;width:9px;height:9px;
  border-radius:50%;background:var(--c-surface);box-shadow:inset 0 0 0 1px var(--c-warm);
  transition:background .18s ease,box-shadow .18s ease}
/* ⚠️ 全局 `a:hover,a:focus{text-decoration:underline}`（0,1,1）会盖过仅 `.hub-link`
   （0,1,0）的 none，且 text-decoration **会向下传播到整个站点块**（标题与说明一起被划上
   下划线）——实测聚焦态确有此现象。故此处把 hover / focus 两个态也一并写在选择器里
   （0,2,0 > 0,1,1），下划线只留给 `.hub-title`。 */
.hub-link,.hub-link:hover,.hub-link:focus{display:block;color:inherit;text-decoration:none}
.hub-title{margin:0 0 6px;font-size:var(--fs-h3)}
.hub-note{margin:0;color:var(--c-ink-2);font-size:var(--fs-sm);line-height:var(--lh-sm)}
/* 入口卡配图（客户 2026-10-07 指定素材）：`saving/` 下四张与子栏目**同名**的配图，
   统一裁为 **3:4 竖版**（660×880 WebP，逐张 ≤80KB；见 `image_pipeline.py` 的 `entry` 规格）。
   置于**节点之下、标题之上**，让「线 → 节点 → 图 → 标题」成一条自上而下的读序；
   节点仍落在顶部那条暖砂线上，不被图遮挡；整卡仍是一个 `<a>`，可点区域不变。 */
.hub-fig{display:block;margin:0;overflow:hidden;border-radius:var(--radius)}
.hub-fig .fig{margin:0}
.hub-fig img{display:block;width:100%;height:auto;border-radius:var(--radius);
  transition:transform .28s cubic-bezier(.2,.7,.2,1)}
/* hover / 键盘聚焦时图片**略微放大**（客户 2026-10-07 指定）。
   ⚠️ 全站既有口径是「卡片 hover 禁止位移与缩放」，本条是客户明确要求后的**例外**，
   故严格限定五条边界：① 只作用于**图片本身**（标题与说明不动，也不影响布局）；
   ② 幅度极小（1.045）；③ `overflow:hidden` 兜住放大后的溢出（配合圆角不露白边）；
   ④ `prefers-reduced-motion` 下 transition 置 none；⑤ 触屏无 hover，自然不会触发。 */
.hub-stop:hover .hub-fig img,.hub-stop:focus-within .hub-fig img{transform:scale(1.045)}
@media (prefers-reduced-motion:reduce){.hub-fig img{transition:none}}
/* 图已无缝拼接（`.hub-chain` gap:0），文字区改由自身内边距拉开 ——
   左 0 是为了让**首列标题仍与页面版心、H1 左边缘对齐**。 */
.hub-text{padding:var(--space-4) var(--space-4) var(--space-5) 0}
.hub-stop:hover::before,.hub-stop:focus-within::before{
  background:var(--c-brand);box-shadow:inset 0 0 0 1px var(--c-brand),0 0 0 4px var(--c-brand-soft)}
.hub-stop:hover .hub-title,.hub-stop:focus-within .hub-title{color:var(--c-brand-dark);
  text-decoration:underline;text-decoration-color:var(--c-brand);
  text-decoration-thickness:1px;text-underline-offset:.18em}
@media (prefers-reduced-motion:no-preference){
  .hub-chain::before{transform-origin:0 50%;animation:hubThread .7s cubic-bezier(.2,.7,.2,1) both}
  .hub-stop::before{animation:hubNode .3s ease-out both}
  .hub-stop:nth-child(1)::before{animation-delay:.22s}
  .hub-stop:nth-child(2)::before{animation-delay:.33s}
  .hub-stop:nth-child(3)::before{animation-delay:.44s}
  .hub-stop:nth-child(4)::before{animation-delay:.55s}
}
@media (prefers-reduced-motion:reduce){
  .hub-chain::before,.hub-stop::before,.hub-stop::after{animation:none!important}
}
@keyframes hubThread{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes hubNode{from{opacity:0}to{opacity:1}}
/* ── 「脉络」的另一种走向：长内容页的竖向骨架（2026-10-07，本地站 /chandi/ 试点）─────
   同一个语汇、换一个走向：hub 页是**横向**脉络（4 个并列条目挂在一横线上）；
   内容页（产地与菌种）没有并列条目，只有纵向的溯源叙述与证据 ——
   故把 hub 在 <860px 已定义好的**竖向脉络**提升为主形态：
   一条暖砂竖线贯穿全页，每个小节标题左侧一枚圆环节点，读到哪一节哪一节点亮。
   · **零内容改动**：`.strain-layout` / `.cert-grid` / `.cert-card` / `.fig-grid` 全部原样
     （`cert_card` 是共用组件，客户已裁定四列网格）—— 节点与竖线都是伪元素，
     `C.section()` 一行未改。
   · 对齐：节点的**左边缘与 H1 左边缘对齐**，竖线穿过节点圆心；正文整体右缩 48px ——
     缩进量足够大，读起来是「有意的版心」而不是「对齐错了」。
   · 节点 = `.sec-title::before`（`top:50%` 落在标题行盒中线）；竖线 = `.sec::after`
     **逐段**绘制（本节点下方 → 下一节点上方，末节不画）—— 逐段是为了绕开
     「一条线算不出末节点位置」的老问题（与 hub 竖排版同一做法）。
     ⚠️ 段末的 `-40px` 与 `.sec{margin:0 0 40px}` 是**耦合**的，改小节间距须同步改这里。
   · 点亮：JS 只加 `.is-current`；**无 JS 时节点保持暖砂环**，结构与内容完全不依赖 JS。 */
.spine{position:relative;padding-left:var(--space-7);
  --spine-node:9px;                        /* 节点直径 */
  --spine-mid:calc(var(--fs-h2) * .7)}      /* h2 行盒中线（行高 1.4 ⇒ 半行 .7em） */
.spine .sec{position:relative}
/* 小节标题不再用品牌红竖条 —— 标记功能交给节点（红色因此更省，面积更小） */
.spine .sec-title{border-left:0;padding-left:0;position:relative}
.spine .sec-title::before{content:"";position:absolute;left:calc(-1 * var(--space-7));
  top:calc(50% - var(--spine-node) / 2);
  width:var(--spine-node);height:var(--spine-node);border-radius:50%;
  background:var(--c-surface);box-shadow:inset 0 0 0 1px var(--c-warm);
  transition:background .25s ease,box-shadow .25s ease}
.spine .sec::after{content:"";position:absolute;
  left:calc(var(--spine-node) / 2 - var(--space-7));
  top:calc(var(--spine-mid) + var(--spine-node) / 2);
  bottom:calc(-40px - var(--spine-mid) + var(--spine-node) / 2);
  width:1px;background:var(--c-warm)}
.spine .sec:last-child::after{display:none}
/* 读到哪一节，哪一节的节点点亮（与 hub 的「进入态」同一视觉） */
.spine .sec.is-current .sec-title::before{
  background:var(--c-brand);box-shadow:inset 0 0 0 1px var(--c-brand),0 0 0 4px var(--c-brand-soft)}
/* 竖线是**逐段连续**的，故 spine 内的小节只做淡入、不做纵向位移
   （位移会让相邻两段在动画过程中错开，看上去像线断了） */
.spine .sec.reveal{transform:none}
/* ── 板块间视觉过渡（2026-10-12 美术测试 · 客户选定「章回体序号 + 色带」）──────
   仅作用于 `.spine--chapter`（**按页开关，当前只有资质页**）——`.spine` 本身
   被 /chandi/、/gongyi/ 共用，直接挂上去会把那两页的板块一起改掉。
   · ① 章回体序号：衬线大字 + **朱砂红**，与标题本体形成字号／颜色双重落差，
     让节与节的边界不依赖分隔线也能读出来（杂志「卷首」体例，也是朱批／
     卷首题字的传统做法）。色取 `--c-brand`(5.91:1，大字远超 3:1 门槛)；
     **不可**用 `--c-warm`(1.70:1，本仓规约禁作文字色)。
   · ② 色带换气：偶数列小节垫白面，与页面底 `--c-surface-2`(宣纸白) 交替 ——
     这是 Stripe / Apple / Tailwind UI 一类站点最通用的 banded sections 做法，
     **不引入任何新色值**，`--c-brand/--c-warm/--c-wood` 主色一概未动。
   · 实现要点：色带是 `::before` + **负 inset 外扩**，绝不给 `.sec` 加
     padding/margin —— 竖线（`left:calc(node/2 - 48px)`）与节点
     （`left:-48px`，须与 H1 左边缘对齐）都是按 `.sec` 的**原盒模型**算的，
     盒模型一动节点就错位。z-index:-1 把色带压到内容之下（配 `isolation`
     把它限制在本小节的层叠上下文内，不会穿透到页面底之下）。
   v2（客户二次裁定）：色带改**不带边框、不圆角的通栏**——横跨整个视口宽度，
     只在上下各外扩 16px 作为「换气」留白；卡片则换回**原本的宣纸白**，
     图版换白面，与色带反相，卡片轮廓不会糊进面板。 */
.spine--chapter{--ord-scale:1.55}
/* ★ 序号用**绝对定位**，彻底不参与 h2 的行盒 —— 放大到 1.55 倍也不会把行盒
   撑高。这是硬要求：`.spine` 的节点按 `top:50%`（行盒中线）定位，而竖线起点
   用的是写死的 `--spine-mid:calc(var(--fs-h2) * .7)`；行盒一旦变高，**节点下沉
   而竖线起点不动**，线就会从节点上方穿过去（实测放大后行盒 42→49px）。
   行盒留白改由 `.sec-title` 的 `padding-left` 预留：汉字数字是全角、宽度＝1em，
   所以 1.55em 能算准，不依赖字体度量。
   `left:0` 取的是 `.sec-title` 的**内边距盒**左缘＝元素左缘（无边框），
   故 padding 不会推动节点 —— `::before{left:-48px}` 仍与 H1 左边缘对齐。 */
.spine--chapter .sec-title{padding-left:calc(var(--ord-scale) * 1em + .4em)}
.spine--chapter .sec-ord{position:absolute;left:0;top:50%;
  transform:translateY(-50%);line-height:1;
  font-family:var(--font-serif);font-size:calc(var(--ord-scale) * 1em);
  font-weight:700;color:var(--c-brand);letter-spacing:.06em}
/* ★ 这里**不能**用 `isolation:isolate`。色带是偶数列小节的 `::before`，
   一旦给它 `isolation`，该小节整体成为层叠上下文、在**文档序更晚**处绘制，
   于是色带上沿（外扩 -16px）会盖住**上一节** `::after` 画过来的那截竖线尾,
   看上去线在进入色带处断了。去掉 isolation 后色带落回根层叠上下文的负层
   （画在所有在流内容之前），竖线在正层 ⇒ 线自然压在色带之上、始终连贯。
   安全性：`.container`/`.main`/`.spine` 均无背景，页面底由 body 背景
   （已上浮为画布背景）承担，故色带不会掉到页面底下。 */
/* 通栏：`left/right` 各外扩 50vw（**不是**常见的 `left:50%+width:100vw`）。
   原因：`.sec` 被 `.spine` 的 48px 缩进推开，**并不在视口中心** —— 实测按
   「50% + 100vw」算出的色带左缘仍在视口内 16.5px、右侧却溢出 32px（= 缩进
   的一半 24px + 滚动条一半 7.5px）。改用两侧各 `-50vw`，无论 `.sec` 偏在哪
   里，`±50vw` 都必定盖满视口，且不依赖 `--space-7` 的具体取值（窄屏缩进
   会变，用固定值补偿会在窄屏失效）。溢出部分由 `body{overflow-x:clip}` 裁掉。 */
.spine--chapter .sec:nth-of-type(even)::before{content:"";position:absolute;
  z-index:-1;top:calc(-1 * var(--space-4));bottom:calc(-1 * var(--space-4));
  left:calc(-1 * 50vw);right:calc(-1 * 50vw);
  background:var(--c-surface)}
/* 节点原本是白面，落到白色通栏上会消失 ⇒ 换成宣纸白，只留暖砂环 */
.spine--chapter .sec:nth-of-type(even) .sec-title::before{background:var(--c-surface-2)}
/* 色带内的卡片反相：卡片回宣纸白、图版回白面 */
.spine--chapter .sec:nth-of-type(even) .cert-card{background:var(--c-surface-2)}
.spine--chapter .sec:nth-of-type(even) .cert-fig img{background:var(--c-surface)}
.fig-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--space-4)}
.fig{margin:0;background:var(--c-surface);border:3px double var(--c-line);border-radius:var(--radius);overflow:hidden}
.fig img{width:100%;height:auto}
.fig figcaption{padding:var(--space-2) var(--space-3);font-size:var(--fs-note);color:var(--c-ink-2);background:var(--c-surface-2)}
.phil-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--space-4)}
.phil-card{background:var(--c-surface);border:1px solid var(--c-line);border-left:3px solid var(--c-brand);border-radius:var(--radius);padding:14px var(--space-4)}
.phil-card h3{margin:0 0 6px;font-size:var(--fs-h3)}
.phil-card p{margin:0;color:var(--c-ink-2);font-size:var(--fs-sm)}
.craft-list,.patent-list,.report-list{display:grid;gap:14px}
.craft,.patent,.report{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);padding:14px var(--space-4)}
.craft-name,.report-name{margin:0 0 6px;font-size:var(--fs-h3)}
.craft-desc{margin:0 0 6px}
.craft-note{margin:0;font-size:var(--fs-note);color:var(--c-compliance)}
.report-meta,.patent .cert-patent{margin:0 0 var(--space-1);font-size:var(--fs-note);color:var(--c-ink-2)}
.report-concl{margin:0;font-size:var(--fs-sm)}
.patent{display:flex;flex-direction:column;gap:var(--space-1)}
.patent-name{font-weight:600;color:var(--c-ink-strong)}
/* 8a-bis. 工艺技术页（2026-10-07 本地测试站）：生产工序 + 专利证书网格
   ── 该页原只有「五项工艺 + 一条专利文字」，介绍单薄、专利无图；本轮用企业提供的
      上墙技术资料与全部专利证书原件补齐。样式仍取既有语汇（细线 + 卡片 + 标签式
      key-value），不引入新色、不引入第二套卡片外观。
   ── 生产工序：四组，组内 `<dt>` 工序名（左列对齐）+ `<dd>` 说明（右列）。
      与「规格行」同源的博物馆标签式：长说明不再与工序名挤成一段。 */
.proc-groups{display:grid;gap:var(--space-6)}
.proc-group-title{margin:0 0 var(--space-4);font-size:var(--fs-h3);color:var(--c-ink-strong)}
.proc-list{display:grid;grid-template-columns:minmax(0,150px) minmax(0,1fr);
  gap:0 var(--space-5);margin:0}
.proc-name{margin:0;padding:var(--space-4) 0;font-size:var(--fs-sm);
  color:var(--c-ink-2);letter-spacing:.04em;border-top:1px solid var(--c-line)}
.proc-desc{margin:0;padding:var(--space-4) 0;border-top:1px solid var(--c-line)}
/* 每行首行不画上边线（`dt`/`dd` 交错，两者各自的第一个即首行两格） */
.proc-name:first-of-type,.proc-desc:first-of-type{border-top:0;padding-top:0}
/* ── 工序组分隔图：每组标题**之前**放两张实拍（车间/实验室），作视觉分段。
      直接复用 `.fig` 观感（细双线 + 图注），不引入第二套卡片外观；
      两张 4:3 并排，与下方 `<dl>` 的 150px 左列对齐同一栅格节奏。 */
.proc-photos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--space-4);margin:0 0 var(--space-5)}
.proc-photos .fig{height:100%}
/* ── 专利证书网格：按专利种类分组，逐件配证书图 + 专利号/种类/授权公告日/专利权人。
      证书统一 900×1200（3:4），故网格可按下限 200px 稳定排 3~4 列。
      **件数不上页**：此处不设任何计数徽标或汇总行。 */
/* ⚠️ 必须写明 `minmax(0,1fr)`：只写 `display:grid` 时隐式列是 `auto`，
   其**下限是内容的 min-content/max-content** —— 内部改成横向滚动（列数不定）后，
   这一列会被撑到内容总宽（实测 1104 → **1460**），滚动容器因此宽过视口，
   内容被 `body{overflow-x:clip}` 裁掉而不是可滚（横向溢出 508 个元素）。
   `minmax(0,1fr)` 把下限显式归零，列宽才等于容器宽。 */
.patent-groups{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-6)}
.patent-group-title{margin:0 0 var(--space-4);font-size:var(--fs-h3);color:var(--c-ink-strong)}
.patent-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));
  gap:var(--space-4);align-items:start}
.patent-card{display:flex;flex-direction:column;gap:var(--space-3);margin:0;
  background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);
  padding:14px}
.patent-title{margin:0;font-size:var(--fs-sm);line-height:var(--lh-sm);color:var(--c-ink-strong)}
.patent-fig{margin:0;border:1px solid var(--c-line);border-radius:var(--radius);
  overflow:hidden;background:#fff}
.patent-fig img{display:block;width:100%;height:auto}
.patent-fig .cert-fig-link{display:block}
/* 字段表沿用 `.cert-fields` 的骨架，只把字号与行距收紧（专利字段比证书多一行） */
.patent-fields{margin:0;gap:3px var(--space-3);font-size:var(--fs-note)}
@media (max-width:719px){
  /* 窄屏：工序改单列（工序名在上、说明在下） */
  .proc-list{grid-template-columns:1fr}
  .proc-name{padding-bottom:0}
  .proc-desc{padding-top:2px}
  /* 窄屏：分隔图改单列（双列时单张仅约 160px 宽，车间实拍细节不可辨） */
  .proc-photos{grid-template-columns:1fr}
  /* 专利卡改**单列**：双列时卡片仅约 160px 宽，`专利号`/`专利权人` 两行的值会被
     拆成「ZL 2022 1 09681 / 07.X」这种断号（实测），且证书缩略图过小。
     单列后字段两栏有 ~250px 可用，与桌面端同一读法。 */
  .patent-grid{grid-template-columns:1fr}
}
.cert-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5);align-items:start}
.cert-col{display:flex;flex-direction:column;gap:0}
.lead{font-family:var(--font-serif);font-size:var(--fs-h3);color:var(--c-ink-strong)}
/* 8b. T04 文章 / 服务网点 / 招商合作 */
.article-meta{display:flex;flex-wrap:wrap;gap:6px 18px;margin:0 0 18px;padding:var(--space-2) 0;
  border-bottom:1px solid var(--c-line);font-size:var(--fs-note);color:var(--c-ink-2)}
.article-meta time{font-variant-numeric:tabular-nums}
.article-body{max-width:var(--maxw-read)}
.article-body p{margin:0 0 14px;line-height:1.9;font-size:var(--fs-body);color:var(--c-ink)}
.outlet-list{display:grid;gap:14px;list-style:none;margin:0;padding:0}
.outlet-addr,.outlet-meta,.outlet-links{margin:0 0 var(--space-1);font-size:var(--fs-sm)}
.outlet-links .pending{font-size:var(--fs-note)}
.invest-contact{background:var(--c-surface-2);border:1px solid var(--c-line);border-left:3px solid var(--c-wood)}
.invest-contact .sec-body{max-width:720px}
.hz-list{display:grid;gap:var(--space-3);list-style:none;margin:0;padding:0}
.hz-item{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--radius);padding:var(--space-3) var(--space-4)}
.hz-name{margin:0 0 6px;font-size:var(--fs-h3)}
.hz-desc{margin:0;color:var(--c-ink-2);font-size:var(--fs-sm)}
.risk-list{margin:0;padding-left:22px;color:var(--c-ink-2)}
.risk-list li{margin:0 0 6px}
/* 8c. 首页：首屏轮播 / 关于我们 / 产品入口卡 / 媒体新闻 */
.sec-body--wide{max-width:100%}
/* 「菌种来源」两栏（客户 2026-10-07）：左＝正文 + 两份菌种鉴定报告，右＝产区配图。
   该区块必须以 `wide=True` 渲染，否则右栏会被 `.sec-body` 的 `--maxw-read`
   （34em≈544px）夹成窄条、正文也失去整行宽度（同「相关认证」踩过的坑）。 */
.strain-layout{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:var(--space-6);align-items:start}
.strain-main .fig-grid,.strain-side .fig-grid{margin:var(--space-4) 0 0}
/* 两份鉴定报告并排：全局 `.fig-grid` 的下限 260px 在 1024 档差 2px 会掉成单列，
   故本区块收到 240px（1024 档左栏 534px → 2×240+16=496 ≤ 534 可并排；
   窄屏单栏时 327px < 496 仍自动回落为 1 列）。 */
.strain-main .fig-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
/* 规格行（2026-10-07 内容排列试点）：把「品种：武芝 GL-8」从**正文段落**里拎出来，
   变成一条独立的 key-value 事实行（上下细线夹持，博物馆藏品标签式）。
   获奖站的 editorial 三段式 —— 长正文（叙述）→ 关键事实（可核对）→ 图版（证据），
   层级由此拉开，长篇品牌正文不再一路平铺到底。**文字未改一字**，仅换容器与层级。 */
.spec-row{display:flex;align-items:baseline;gap:var(--space-5);flex-wrap:wrap;
  margin:var(--space-5) 0 0;padding:var(--space-4) 0 0;border-top:1px solid var(--c-line)}
.spec-row dt{font-size:var(--fs-note);color:var(--c-ink-2);letter-spacing:.1em}
.spec-row dd{margin:0;font-family:var(--font-serif);font-weight:600;
  font-size:var(--fs-h3);color:var(--c-ink-strong)}
/* 图版编号（2026-10-07 内容排列试点）：`.strain-layout` 内所有 `.fig-grid .fig`
   按 **DOM 顺序**连续编号（正文 2 件鉴定证书 → 侧栏 2 张产区实拍 = 图 01…04）。
   计数器挂在 `.strain-layout` 上，故跨两个 `.fig-grid` 仍连续；`.cert-grid` 内的
   `.cert-fig` 不在该容器内，**不会被编号**。图注文字本身一字未改，编号走伪元素。 */
/* 图版编号（2026-10-07 客户裁定：**推广到全站**）：每页从 01 连续（`.page` 重置），
   跨 `.fig-grid` 仍连续 ⇒ 形成「图版目录」。`.strain-layout` 内的重置保留，
   使 `/chandi/` 的 4 张（2 件鉴定证书 + 2 张产区实拍）自成 01–04。
   `.cert-fig`（证书卡内缩略图）不在 `.fig-grid` 内 ⇒ **不会被编号**。
   同为伪元素 ⇒ 编号不进 DOM 文本，**对 GEO 零影响**。 */
.page{counter-reset:plate}
.fig-grid .fig{counter-increment:plate}
.fig-grid figcaption::before{content:"图 " counter(plate,decimal-leading-zero) " · ";
  font-family:var(--font-serif);color:var(--c-warm)}
.strain-layout{counter-reset:plate}
@media (max-width:1023px){.strain-layout{grid-template-columns:1fr}}
/* 首屏轮播（手动切换：左右箭头 + 指示点；无自动播放、无动效抢占注意力）
   客户反馈第 1、2 项：轮播为**全宽无缝横幅** —— 由文档壳插在 `<main class="container">`
   之前（见 layout.render_page 的 pre_main），所以宽度天然等于视口宽，无需 100vw
   （100vw 含滚动条宽度会造成横向溢出）。上沿紧贴页头，去圆角去边框。
   高度对齐原站首页 `height:537px;width:100%` 的做法，做成随视口收缩的 clamp。 */
.hero-carousel{position:relative;margin:0;background:var(--c-ink-strong);overflow:hidden;border:0;border-radius:0;box-shadow:none}
.carousel-track{position:relative;height:clamp(200px,37vw,537px)}
.carousel-slide{display:none}
.carousel-slide:first-child{display:block}
.carousel-slide img{width:100%;height:100%;object-fit:cover;display:block}
.carousel--ready .carousel-slide{display:none}
.carousel--ready .carousel-slide.is-active{display:block}
/* 垂直居中用 translateY（静态定位，非 hover 位移，保留） */
.carousel-btn{display:none;position:absolute;top:50%;transform:translateY(-50%);width:var(--touch);height:var(--touch);padding:0;border:0;border-radius:50%;background:rgba(36,29,27,.58);color:#fff;font-size:26px;line-height:1;cursor:pointer;align-items:center;justify-content:center}
.carousel--ready .carousel-btn{display:flex}
.carousel-btn:hover,.carousel-btn:focus{background:var(--c-brand);color:#fff}
.carousel-prev{left:var(--space-3)}
.carousel-next{right:var(--space-3)}
.carousel-dots{display:none;position:absolute;left:0;right:0;bottom:var(--space-3);justify-content:center;gap:10px}
.carousel--ready .carousel-dots{display:flex}
.carousel-dot{width:12px;height:12px;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.55);cursor:pointer}
.carousel-dot.is-active{background:var(--c-brand-on-dark);box-shadow:0 0 0 2px rgba(255,255,255,.75)}
/* 关于我们：左右双栏（正文 + 展示图），数字卡横铺整宽
   客户反馈第 5 项：正文右侧新增一张展示图片的位置 */
.about-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:var(--space-6);align-items:start;margin:0 0 var(--space-5)}
.about-text{max-width:var(--maxw-read)}
.about-figure{margin:0}
.about-figure img{width:100%;height:auto;border:3px double var(--c-line)}
@media (max-width:1023px){.about-grid{grid-template-columns:1fr}}
/* 引言段落用衬线，增强「碑记」质感；段落单独限宽（34em） */
.about-intro{font-family:var(--font-serif);font-size:var(--fs-h3);line-height:1.9;color:var(--c-ink-strong);margin:0}
/* 首页「关于我们」事实清单（2026-10-06 GEO 正文补全）
   全局 `ul,ol{margin:0;padding:0;list-style:none}` 会把它压成无缩进无圆点的纯文字堆叠，
   故在此恢复列表语义的视觉表现；正文色降一档，与引言段拉开层次。 */
.about-facts{margin:18px 0 0;padding-left:22px;list-style:disc;color:var(--c-ink-2)}
.about-facts li{margin:0 0 8px;line-height:1.8}
.about-facts li a{color:var(--c-wood)}
.more-link{margin:var(--space-4) 0 0}
.more-link a{font-weight:600;display:inline-flex;align-items:center;min-height:var(--touch);color:var(--c-brand-dark)}
/* 章节标题作为链接（客户反馈第 3 项：删除「了解更多」，链接挂到标题上） */
.sec-title-link{color:inherit;display:inline-flex;align-items:center;gap:.35em}
.sec-title-link:hover{color:var(--c-brand-dark);text-decoration:none}
.sec-title-arrow{font-size:.72em;color:var(--c-brand);transition:color .15s ease}
.sec-title-link:hover .sec-title-arrow{color:var(--c-brand-dark)}
/* 产品入口图片卡：客户反馈第 6 项 —— **固定一行、左右滑动**（不再自动折行） */
.pcard-grid{display:flex;flex-wrap:nowrap;gap:20px;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;padding-bottom:var(--space-3);
  scrollbar-width:thin;scrollbar-color:var(--c-ink-2) transparent}
.pcard{flex:0 0 360px;scroll-snap-align:start;display:block;background:var(--c-surface);
  border:1px solid var(--c-line);border-radius:var(--radius);overflow:hidden;color:var(--c-ink)}
/* 窄屏卡片收窄，避免一屏只露出小半张 */
@media (max-width:767px){.pcard{flex:0 0 280px}}
.pcard-grid::-webkit-scrollbar{height:8px}
.pcard-grid::-webkit-scrollbar-thumb{background:var(--c-ink-2);border-radius:4px}
.pcard-grid::-webkit-scrollbar-track{background:var(--c-line);border-radius:4px}
.pcard:hover,.pcard:focus{text-decoration:none;border-color:var(--c-brand);box-shadow:var(--shadow-2)}
.pcard:focus-visible{outline:2px solid var(--c-brand);outline-offset:2px}
.pcard-fig{aspect-ratio:16/9;overflow:hidden;background:var(--c-surface-2)}
.pcard-fig img{width:100%;height:100%;object-fit:cover}
.pcard-body{padding:14px var(--space-4) 18px;border-top:1px solid var(--c-line)}
.pcard-title{margin:0;font-size:var(--fs-h3);color:var(--c-ink-strong)}
/* 客户反馈第三轮第 3 项：产品卡只保留标题，详细说明暂不渲染。
   `.pcard-desc` 规则保留，企业后续要恢复说明时直接改 product_entries() 即可。 */
.pcard-desc{margin:6px 0 0;font-size:var(--fs-sm);color:var(--c-ink-2)}
/* 媒体新闻：左侧**图片轮播**（与首图轮播同构）+ 右侧文字列表（客户反馈第 7 项） */
.news-grid{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:var(--space-6);align-items:start}
@media (max-width:1023px){.news-grid{grid-template-columns:1fr}}
/* 新闻轮播：复用 `.hero-carousel` 的骨架与脚本，只覆盖与首图不同之处 ——
   track 不设固定高（由当前屏的内容撑开）、圆角与底色回退为普通卡片观感、
   指示点移到卡片**下方**（落在白底标题区上会压住文字）。 */
.news-carousel{background:transparent;box-shadow:none;border:0;border-radius:var(--radius);overflow:visible}
.news-carousel .carousel-track{height:auto;padding-bottom:34px}
.news-carousel .ncard{border:1px solid var(--c-line);border-radius:var(--radius)}
.news-carousel .carousel-dots{bottom:0}
.news-carousel .carousel-dot{background:rgba(36,29,27,.22)}
.news-carousel .carousel-dot.is-active{background:var(--c-brand);box-shadow:none}
/* 单屏一条：卡片撑满轮播宽度，图片按 4:3 展示 */
.news-carousel .ncard-fig{aspect-ratio:4/3;overflow:hidden;background:var(--c-surface-2)}
.news-carousel .ncard-fig img{width:100%;height:100%;object-fit:cover}
/* 无原站配图的条目：不补造图片，改用等高的栏目名纸色卡 */
.news-carousel .ncard-fig--empty{display:flex;align-items:center;justify-content:center;
  background:var(--c-surface-2)}
.news-carousel .ncard-fig--empty span{font-family:var(--font-serif);font-size:var(--fs-h2);color:var(--c-ink-2)}
.news-carousel .ncard-body{padding:12px var(--space-4) var(--space-4);border-top:1px solid var(--c-line)}
.news-carousel .ncard-title{display:block;font-family:var(--font-serif);font-size:var(--fs-body);
  line-height:1.6;color:var(--c-ink-strong)}
.news-carousel .ncard-link{text-decoration:none}
.news-carousel .ncard-link:hover .ncard-title{color:var(--c-brand-dark)}
/* 媒体新闻列表（左右双线，形似目录页） */
.news-list{border-top:2px solid var(--c-ink-strong);margin:0}
.news-item{display:flex;align-items:baseline;gap:14px;padding:var(--space-3) 0;border-bottom:1px solid var(--c-line)}
.news-date{flex:0 0 auto;font-size:var(--fs-note);color:var(--c-wood);font-variant-numeric:tabular-nums}
.news-title{font-family:var(--font-serif);font-size:var(--fs-body);color:var(--c-ink-strong)}
.news-title:hover{color:var(--c-brand-dark)}
/* 9. 响应式 */
@media (max-width:1023px){.card-fig,.outlet-fig{flex-basis:180px;max-width:180px}
  .cert-cols{grid-template-columns:1fr}
  /* 品牌沿革两栏在窄屏堆叠：时间轴在上、企业理念在下；取消吸附避免遮挡内容 */
  .tl-layout{grid-template-columns:1fr}
  .tl-philosophy{position:static;padding-left:0;padding-top:var(--space-5);
    border-top:1px solid var(--c-line);margin-top:var(--space-5)}}
/* 武夷灵芝「脉络」：<860px 转为**竖向脉络**——同一条线的另一种走向。
   横向 4 列在窄屏会把说明压成逐字竖排，且四列等宽不再成立；
   改竖排后：线在左（每段自本节点下方连到下一个节点上方，末节点无段，故不会越出），
   节点对齐标题首行中线（h3 20px×1.5＝30px 行盒，中线 15px ⇒ 节点 top:10px）。 */
@media (max-width:859px){
  .hub-chain{grid-template-columns:1fr;gap:0}
  .hub-chain::before{display:none}
  .hub-stop{padding-top:0;padding-left:var(--space-5);padding-bottom:var(--space-5)}
  .hub-stop:last-child{padding-bottom:0}
  .hub-stop::before{top:10px}
  .hub-stop::after{content:"";position:absolute;left:4px;top:19px;bottom:-10px;width:1px;
    background:var(--c-warm)}
  .hub-stop:last-child::after{display:none}
  /* 竖排脉络下，3:4 竖版图**整幅**会一张占掉近一屏（4 张数屏），故在竖排里改
     「左图右文」的横向卡。用 flex 而非 grid：`hub-fig` 缺席的条目（将来若把 hub
     复用到没有配图的栏目页）不会被挤进空列。竖排的节点由 `.hub-stop::before` 渲染，
     故把 `hub-node` 占位 span 隐藏，避免它成为 flex 项。 */
  .hub-node{display:none}
  .hub-link{display:flex;gap:var(--space-4);align-items:flex-start}
  .hub-fig{flex:0 0 84px;margin:0}
  .hub-text{flex:1 1 auto;min-width:0;padding:0}   /* 左图右文，无需桌面端的拼图内边距 */
}
@media (max-width:767px){
  /* h1/h2 字号已由 clamp() 流体接管，此处不再重复覆盖 */
  /* 「脉络」竖向骨架窄屏：版心缩进由 48 收到 24，节点/竖线随之内移 */
  .spine{padding-left:var(--space-5)}
  .spine .sec-title::before{left:calc(-1 * var(--space-5))}
  .spine .sec::after{left:calc(var(--spine-node) / 2 - var(--space-5))}
  .header-inner{flex-wrap:wrap;min-height:56px}
  .nav-toggle{display:inline-flex;align-items:center}
  .main-nav{margin-left:0;width:100%;display:none}
  .main-nav.open{display:block}
  .nav-list{flex-direction:column;gap:0;padding-bottom:10px}
  .nav-item>a{padding:10px var(--space-1)}
  .submenu{position:static;display:block;box-shadow:none;border:0;background:transparent;padding:0 0 0 14px;border-top:0}
  .submenu li a{color:#E0D6C8;padding:var(--space-2) 6px}
  .header-cta{margin-left:0}.header-cta .tel{display:none}
  .card,.outlet{flex-direction:column}
  .card-fig,.outlet-fig{flex-basis:auto;max-width:100%}
  .fact-table th{width:40%}.sec-body{max-width:100%}
  .carousel-btn{width:38px;height:38px;font-size:22px}
  .carousel-prev{left:var(--space-2)}.carousel-next{right:var(--space-2)}
  .news-item{flex-direction:column;gap:var(--space-1)}
  .stat-num{font-size:30px}
  /* 引言段落 20px 衬线在窄屏偏大，降一档 */
  .about-intro{font-size:18px}
}
/* 10. 偏好 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}
@media (prefers-color-scheme:dark){:root{--c-surface-2:#EFEBE3}}

/* ═══════════════════════════════════════════════════════════════════════════
   线上同步区块（2026-10-12）：产地优势 / 技术优势
   ───────────────────────────────────────────────────────────────────────────
   这两节的 CSS 原本只存在于**易优线上内容**里（10-08 晚间直接改在线上），
   本地 site.css 一直没有。本轮把线上内容反向同步回本地，样式一并回迁，
   类名与线上保持一致，将来再上线时两份产物才不会再分叉。
   注：线上那份还多一段「易优站点框架适配层」（`#ny-main p` 提权、
   `--site-header-h` 的 scroll-margin-top），那是**站点外壳专属**，不属于本站，
   故**不回迁**。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 产地优势 · 前段「左文右图」并排（九曲溪图不再独占整行） ────────────── */
.pros-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,0.85fr);
  gap:var(--space-6);align-items:start;margin:var(--space-4) 0 var(--space-2)}
.pros-main>*:first-child{margin-top:0}
/* ── 产地优势 · 检测报告图组：沿用 .fig 卡片观感，但不参与图版编号 ────────── */
.report-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--space-4);margin:var(--space-4) 0 var(--space-5)}
.report-grid .fig{margin:0}
/* ── 破壁率/孢子油报告图组：flex 定宽 —— 三张同一行、每张 210px
      （竖版报告若按 1fr 分栏会撑破列宽，见 `00-知识库/14` §24.3） ──────────── */
.report-grid--tight{display:flex;flex-wrap:wrap;gap:var(--space-4);
  margin:var(--space-4) 0 var(--space-5)}
.report-grid--tight>figure{flex:0 0 210px;max-width:210px;min-width:0;margin:0}
.report-grid--tight img{display:block;width:100%;height:auto}

/* ── 技术优势：左文右证，证书图全页唯一 ─────────────────────────────────── */
.tech-list{display:grid;gap:var(--space-5)}
.tech-item{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,250px);
  gap:var(--space-5);align-items:start;border-top:1px solid var(--c-line);
  padding-top:var(--space-4)}
.tech-item:first-child{border-top:0;padding-top:0}
.tech-item--solo{grid-template-columns:1fr}
.tech-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.55fr);
  gap:var(--space-6);align-items:start;margin-top:var(--space-5);
  border-top:1px solid var(--c-line);padding-top:var(--space-4)}
.tech-texts h3{margin:0 0 var(--space-2);font-size:var(--fs-sm);color:var(--c-brand-dark)}
.tech-texts h3:not(:first-child){margin-top:var(--space-4)}
.tech-texts p{margin:0}
.tech-fig{margin:0;border:1px solid var(--c-line);border-radius:var(--radius);
  overflow:hidden;background:var(--c-surface)}
.tech-fig img{display:block;width:100%;height:auto}
.tech-fig .cert-fig-link{display:block}
.tech-fig figcaption{padding:6px 10px;font-size:var(--fs-note);color:var(--c-ink-2);
  background:var(--c-surface-2)}
.tech-certs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-4)}
.tech-certs .tech-fig{margin:0}

/* 窄屏：并排一律降为单列（与线上断点一致：1000px 降并排、719px 降图组） */
@media (max-width:1000px){
  .cert-grid,.report-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pros-cols{grid-template-columns:1fr;gap:var(--space-4)}
  .tech-split{grid-template-columns:1fr}
}
@media (max-width:859px){
  .tech-item{grid-template-columns:1fr}
}
@media (max-width:719px){
  .cert-grid,.report-grid{grid-template-columns:1fr}
  .tech-certs{grid-template-columns:1fr}
  .report-grid--tight>figure{flex:1 1 0;max-width:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   「档册」（2026-10-12）
   ───────────────────────────────────────────────────────────────────────────
   这一天做了两页：`/wuyilingzhi/zizhi/`（章回体序号 + 回纹窗框 + 逐段对齐）
   与 `/chanpin/baojianshipin/`（大幅实拍 + 细线分隔的规格档案）。两页表面不同，
   底子是同一件事 —— **把可核对的凭据排成能逐条查阅的档册**：批文、专利号、
   检测报告、时间节点、产地证明，本来就是这家企业最主要的内容。

   所以本次不新造语言，而是把今天那两页的**装帧逻辑**推广到其余页面：

     竖线开条 · 细线收口 · 圆角归零 · 阴影只留给真正浮起的层

   注意竖线不是新发明的母题 —— 站点原有的 `.sec-title`（品牌红 3px）、
   `.note`（木色 3px）、`.purchase`（暖灰 3px）本来就是竖线语法，本次只是让它
   **在入口列表与事实表上也成立**，全站由此收敛到一个母题。

   作用域：`.ui2`（挂在 `<body>`，由 `data/pages.py` 在清单层打标）。
   客户裁定的排除页（`/zhiliang/`、`/xinwen/*`、`/hezuo/*`、404）**不挂**该类，
   输出与视觉均**逐字节不变**；`.entry-card` / `.fig` 这些跨页共用组件也因此
   不会被误伤。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ① 入口卡 → 竖线档条 -------------------------------------------------------
   原来是"等权圆角卡网格"：同圆角、同边框、同 hover 阴影 —— 三张一套，
   读起来像通用模板，而且把「注册类保健食品 / 普通食品 / 服务」这三种**合规身份
   完全不同**的东西抹成了等权。改为一行一条的档条：左侧品牌红竖线标出条目起点，
   1px 暖砂细线收口，信息层级交给字体（标题衬线、说明暖灰）。 */
.ui2 .entry-grid{display:block}
.ui2 .entry-card{background:transparent;border:0;border-radius:0;box-shadow:none;
  position:relative;padding:var(--space-4) 0 var(--space-4) var(--space-5);
  border-bottom:1px solid var(--c-line)}
.ui2 .entry-grid>.entry-card:first-child{border-top:1px solid var(--c-line)}
.ui2 .entry-card::before{content:"";position:absolute;left:0;top:var(--space-4);
  bottom:var(--space-4);width:3px;background:var(--c-brand)}
.ui2 .entry-card:hover{box-shadow:none;border-top-color:var(--c-line)}
.ui2 .entry-card:hover::before{background:var(--c-brand-dark)}
.ui2 .entry-title{font-family:var(--f-title);margin:0 0 4px}
.ui2 .entry-title a:hover{color:var(--c-brand-dark)}
.ui2 .entry-note{max-width:var(--maxw-read)}

/* ② 事实表 → 档册 -----------------------------------------------------------
   原表是"带外框的盒子 + 偶数行米色斑马纹"：外框把一张本来只是键值对照的表
   装成了卡片，斑马纹则是纯装饰（行本来就已经有 1px 分隔线，两条线在说同一件事）。
   去掉盒与斑马纹，只留"字段列 + 细线行"，与 `.vrow-fields`、`.proc-list`
   这两处既有的键值排版合成一套。 */
.ui2 .fact-table{background:transparent;border:0;border-radius:0;
  border-top:1px solid var(--c-line);border-bottom:1px solid var(--c-line);
  margin:0 0 var(--space-5)}
.ui2 .fact-table th,.ui2 .fact-table td{padding:12px 0;
  border-bottom:1px solid var(--c-line)}
.ui2 .fact-table th{background:transparent;width:30%;padding-right:var(--space-5);
  font-weight:600;color:var(--c-ink-2)}
.ui2 .fact-table tr:nth-child(even) td{background:transparent}
.ui2 .fact-table tr:last-child th,.ui2 .fact-table tr:last-child td{border-bottom:0}

/* ③ 图版：双线框 → 1px 细线 --------------------------------------------------
   `.fig` 原为 `3px double`（纸质画框），但今天的规格档案、技术优势、报告图组
   全部用 1px 细线。同一站里两种画框没有信息含义，只是不统一，故收敛到细线。 */
.ui2 .fig{border:1px solid var(--c-line)}
.ui2 .hero{border:1px solid var(--c-line);border-radius:0}
.ui2 .about-figure img{border:1px solid var(--c-line)}

/* ④ 圆角与阴影归零 -----------------------------------------------------------
   参照页的卡片（`.cert-grid--plate .cert-card`）是 `border-radius:0`，
   本次让范围内的其它卡片与之同族。阴影只保留给真正浮起的层（下拉菜单等），
   静态卡片一律不用——阴影是"浮起"的语义，平铺内容不需要。 */
.ui2 .card,.ui2 .patent-card,.ui2 .phil-card,.ui2 .note,.ui2 .purchase,
.ui2 .news-carousel .ncard,.ui2 .card-fig img,.ui2 .hero{border-radius:0}

/* ── 灵芝衍生产品图版式（2026-10-13）─────────────────────────────────────
   每个品类一张竖版实拍。竖版图占满 1152px 容器会拉到约 1700px 高，
   故左栏封顶 380px，右侧留给事实表 —— 与保健食品规格条目「图在前、字段在后」
   同一逻辑，不新造版式。无图的产品不套这层网格，输出与改动前一致。 */
.prod-layout{display:grid;grid-template-columns:minmax(0,380px) minmax(0,1fr);
  gap:var(--space-6);align-items:start}
.prod-fig{margin:0}
.prod-fig .fig{margin:0}
.prod-facts{min-width:0}
@media (max-width:859px){.prod-layout{grid-template-columns:1fr}}

/* ── 购买渠道「并入产品详情」（2026-10-13，灵芝衍生）─────────────────────
   位置：**右栏事实表之下**（首版挂在 `.prod-layout` 之外，掉到了左栏图片下方）。
   外观：**带边框卡片**（客户 2026-10-13 二次裁定「做卡片边框环绕以示区分」）。
   ⚠️ 同日前一版曾在链接前挂电商平台标记，客户当日撤回（「算了还是别挂 logo 了」），
      已连同 `shop_logo()` 与 `.shop-logo` 一并移除。
   语义：元素与类名仍是 `<aside class="purchase">` —— 视觉变、语义不变，
        `check_site` 的 V24（外链必须带 rel）与 V29（D1 阶段化）照旧生效。
   ⚠️ 本块曾把散文续写在注释终止符之后（等于把后续规则整条丢弃），已改为单条注释；
      注意：注释**正文里也不得出现注释终止符本身**，否则注释会提前结束。
      参见 `.workbuddy/memory` 的 CSS 注释纪律。 */
.purchase--inline{background:var(--c-surface);border:1px solid var(--c-line);
  border-radius:0;padding:var(--space-4);margin:var(--space-5) 0 0}
.purchase--inline .purchase-note{color:var(--c-ink-2);margin:0 0 var(--space-2)}
.purchase--inline .purchase-text{margin:0;font-weight:400}
.purchase--inline .purchase-links{gap:0 var(--space-5);margin:0}

.purchase--inline .purchase-links a{color:var(--c-wood)}
.purchase--inline .purchase-links a:hover{color:var(--c-brand-dark)}

