/* ==========================================================================
   Hypersemi 前台样式
   --------------------------------------------------------------------------
   设计说明（重要）

   视觉规范提取自老站，但代码完全重写：

     老站做法：html{font-size: calc(100vw / 1920 * 100)}，全站用 rem 表达尺寸，
               字号写成 .s16{font-size: calc(16 * 1rem / 100)}。
               结果是 —— 屏幕一窄，整站所有元素和文字等比缩小。
               在 1366×768 的笔记本上，26px 的产品名会缩到 18.5px，
               版心缩到 1024px；老站不得不用 30 多个 @media 断点去补救，
               断点之间依然错位，移动端甚至要靠另一套固定 px 覆盖。

     新站做法：版心固定 1440px（≥1440 视口不再缩放），
               字号用 px + clamp()，断点只有 6 个。

   为什么这样改（对 SEO/GEO 的实际影响）：
     · 正文与标题不再随视口缩小 -> 移动可用性评分（Core Web Vitals 里的
       INP/CLS 与文字可读性）明显改善；
     · 老站 style.css 165KB + 页面内联样式，其中大量是逐断点重复覆盖；
       这里压到约 20KB，首屏 CSS 传输量降一个数量级 -> LCP 受益；
     · 版心不再跟着视口编码，Google 抓取时的像素基准稳定，不存在「同一个
       URL 在不同设备上 DOM 结构/布局差异巨大」造成的移动优先索引问题。

   视觉上（1440px 及以上）与老站保持一致：同一套配色、同一套栅格、
   同一套间距节奏，客户看不出差别。
   ========================================================================== */

/* ---------- 变量 ---------- */
:root {
    --hs-blue:        #0169b2;   /* ★ 全站唯一品牌蓝 = logo 实测主色（#296-②，2026-09-24） */
    --hs-blue-dark:   #01538d;   /* 仅首页 hero/mid 大底用（已定稿）；按钮 hover 等已归一进 --hs-blue */
    --hs-blue-light:  #e8f2fa;   /* ★ 全站唯一浅蓝底/边框 tint（原 c9e0f2/cfe3f3/d7e8f6/d8e9f6 已归一） */
    --hs-orange:      #ff9415;
    --hs-orange-dark: #e58000;
    --hs-bg:          #f4f7fb;
    --hs-white:       #ffffff;

    --hs-text:        #333333;
    --hs-text-2:      #555555;
    --hs-text-3:      #666666;
    --hs-text-mute:   #999999;

    --hs-line:        #eeeeee;
    --hs-line-2:      #f0f0f0;
    --hs-line-3:      #dddddd;

    --hs-container:   1440px;   /* 版心，对应老站 max-width:14.4rem */
    --hs-header:      1600px;   /* 页头容器，对应老站 max-width:16rem */

    --hs-radius:      2px;
    --hs-shadow:      0 1px 4px #eeeeee;
}

/* ---------- 基础 ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background-color: var(--hs-bg);
    color: var(--hs-text);
    font-family: Arial, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; border: 0; }
a { color: inherit; text-decoration: none; transition: color .2s ease; }
a:hover { color: var(--hs-blue); }
ul, ol, dl, dd { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; }
p { margin: 0 0 1em; }
button { font: inherit; cursor: pointer; }

/* 键盘可达性：老站完全没有 focus 样式，键盘用户无法定位 */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--hs-orange);
    outline-offset: 2px;
}

/* 屏幕阅读器专用（结构化标题层级用，不改变视觉） */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ==========================================================================
   页头
   ========================================================================== */
.hd-top {
    background-color: var(--hs-blue);
    color: var(--hs-white);
    font-size: 16px;
}
.hd-inner {
    width: 100%;
    max-width: var(--hs-header);
    margin: 0 auto;
    padding: 0 30px;
}
.hd-top-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 42px;
    gap: 20px;
}
.hd-slogan { opacity: .92; max-width: 100%; overflow-wrap: break-word; }
.hd-top-rt { display: flex; align-items: center; gap: 24px; }
.hd-top-link { color: var(--hs-white); opacity: .92; }
.hd-top-link:hover { color: var(--hs-white); opacity: 1; font-weight: 700; }
.hd-lang {
    display: inline-block;
    padding: 2px 12px;
    border: 1px solid rgba(255, 255, 255, .6);
    border-radius: var(--hs-radius);
    color: var(--hs-white);
    font-size: 14px;
    line-height: 1.6;
}
.hd-lang:hover { background-color: var(--hs-white); color: var(--hs-blue); }

/* 顶栏站内搜索的样式：★ 2026-09-19 随顶栏搜索框一起删除（台账 #160 A）。

   为什么连样式一起删，而不是"先留着万一以后要"：
   · 顶栏那个位子以后要放「站内 AI 选型助手」入口（台账 #159 A），它是**首屏浅底**样式，
     和这里深蓝顶栏上半透明白的输入框不是一套东西，复用不上；
   · 留着就是死代码 —— 正是 #157 刚立下的规矩：不留「改了没反应 / 谁也不引用」的孤儿。
   · 站内搜索本身没删：/search 路由 + 页脚（.ft-search）表单都还在，手机端也走页脚。
   要恢复的话，这 7 条规则在 git 历史 / main.css.bak-20260918 里都有。 */

.hd-main { background-color: var(--hs-white); box-shadow: var(--hs-shadow); position: relative; z-index: 60; }
.hd-main-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 100px;      /* 对应老站 .h-link / .h-j 的 1rem = 100px */
    gap: 20px;
}
.hd-logo { display: block; flex: 0 0 auto; }
.hd-logo img { height: 27px; width: auto; display: block; }
.hd-logo-text { font-size: 22px; font-weight: 700; color: var(--hs-blue); }

.hd-nav { flex: 1 1 auto; }
.hd-menu { display: flex; justify-content: flex-end; align-items: stretch; position: relative; }
.hd-menu-item { position: relative; }
.hd-menu-link {
    display: block;
    height: 100px;
    line-height: 100px;
    padding: 0 20px;
    font-size: 18px;
    font-weight: 700;
    color: var(--hs-text);
    white-space: nowrap;
}
.hd-menu-link:hover,
.hd-menu-item.is-active > .hd-menu-link { color: var(--hs-blue); }

/* 下拉 / 产品大菜单
   ------------------------------------------------------------------
   ⚠ 这块是**全站横向溢出的唯一起源**，动它之前先看清楚为什么这么写。

   原始写法（2026-09-16 之前）：两个面板都 `left:50% + translateX(-50%)`，
   定位基准取各自的菜单项（`.hd-menu-item` 有 position:relative）。菜单项是右对齐的，
   于是 ——
     · 1240px 的产品大菜单从菜单项两侧各探出 620px。中文站实测面板 286~1526，
       越出视口右边界 86px（英文站菜单文字短，刚好没越界，所以中英文表现不一样）；
     · 220px 的小下拉挂在最右那个菜单项上也探出去（实测 1241~1461，越界 21px）。
   关键在于：**越界的部分即使 `visibility:hidden` 藏着，照样计入可滚动区域**
   （hidden 不吃布局），于是全站每一页都多一条横向滚动条。

   现在改成让面板**结构上不可能越界**，并且不用任何魔法数字：
     · 小下拉   —— 右对齐自己的菜单项、朝左展开。菜单整体右对齐，所以右边界
                  结构上不可能越界；菜单左侧有 logo 占位，左边界也够用
                  （1025px 以上实测无左侧越界）。
     · 产品大菜单 —— 定位基准从「菜单项」挪到「整行菜单」（.hd-menu 设 relative、
                  带大菜单的那一项设 static），宽度取整行的 100%。
                  面板宽度恒等于菜单行宽，菜单行本身在容器内 → 恒不越界。
                  基准选择器用 `:has(> .hd-mega)` 而不是复用 `.is-products`：
                  两者不等价 —— `is_products` 为真但 `cat_mega` 为空时，
                  模板渲染的是 `.hd-sub`，用 `.is-products` 会把那种情况下的
                  小下拉基准也一起挪走。
   ------------------------------------------------------------------ */
.hd-sub, .hd-mega {
    position: absolute;
    top: 100%;
    background-color: var(--hs-white);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .12);
    border-top: 3px solid var(--hs-blue);
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s ease, transform .18s ease, visibility .18s;
    z-index: 70;
}
.hd-menu-item:hover > .hd-sub,
.hd-menu-item:hover > .hd-mega,
.hd-menu-item:focus-within > .hd-sub,
.hd-menu-item:focus-within > .hd-mega {
    opacity: 1;
    visibility: visible;
}

/* 小下拉：右对齐菜单项，朝左展开 */
.hd-sub { left: auto; right: 0; transform: translateY(8px); min-width: 220px; padding: 12px 0; }
.hd-menu-item:hover > .hd-sub,
.hd-menu-item:focus-within > .hd-sub { transform: translateY(0); }
.hd-sub li a { display: block; padding: 9px 24px; font-size: 16px; color: var(--hs-text-2); }
.hd-sub li a:hover { background-color: var(--hs-bg); color: var(--hs-blue); }

/* 产品大菜单：定位基准 = 整行菜单，宽度 = 整行 100% */
.hd-menu-item:has(> .hd-mega) { position: static; }
.hd-mega { left: 0; right: 0; transform: translateY(8px); padding: 30px 34px; }
.hd-menu-item:hover > .hd-mega,
.hd-menu-item:focus-within > .hd-mega { transform: translateY(0); }
.hd-mega-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px 32px; }
.hd-mega-title { display: block; font-size: 16px; font-weight: 700; color: var(--hs-blue); margin-bottom: 8px; }
.hd-mega-title:hover { color: var(--hs-orange); }
.hd-mega-list li a { display: block; padding: 3px 0; font-size: 15px; color: var(--hs-text-2); }
.hd-mega-list li a:hover { color: var(--hs-blue); padding-left: 3px; }

.hd-burger { display: none; width: 42px; height: 42px; border: 1px solid var(--hs-line-3); background: none; padding: 10px; }
.hd-burger span { display: block; height: 2px; background: var(--hs-text); margin: 4px 0; }

/* ==========================================================================
   面包屑
   ========================================================================== */
/* ★ 2026-09-24（JACK 第 1 条）：面包屑条原来**没有背景色** ⇒ 整条 54px 露出 body 灰底，
   在白色页头与白色 `.cl` 之间夹出一条灰带（读起来就是"一块灰"）。
   补白底 ⇒ 页头 / 面包屑 / 正文连成一整片白，与首页同构。 */
.bc { padding: 15px 30px; background-color: var(--hs-white); }
.bc-inner { max-width: var(--hs-container); margin: 0 auto; }
.bc-list { display: flex; flex-wrap: wrap; align-items: center; font-size: 15px; color: var(--hs-text-3); justify-content: flex-end; }
.bc-item { display: flex; align-items: center; }
.bc-item + .bc-item::before { content: '-'; margin: 0 8px; color: var(--hs-text-mute); }
.bc-item:first-child a { padding-left: 22px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23666' d='M8 1 15 7h-2v8h-3V10H6v5H3V7H1z'/%3E%3C/svg%3E") left center / 14px 14px no-repeat; }
.bc-item a:hover { color: var(--hs-blue); }
.bc-item [aria-current] { color: var(--hs-text); }

/* ==========================================================================
   产品详情页
   ========================================================================== */
/* ★★★ 2026-09-24（JACK 第 1 条：「产品页的背景和首页保持一致，不要有块状阴影」）
   --------------------------------------------------------------------------
   1680 档实测（`_style_probe.js`）改前的真相：
     body  w=1680 bg=#f4f7fb(灰)
     .pd   w=1680 bg=**transparent**          ← 露 body 灰底
     .pd-hero        w=1440 bg=transparent mar=0/90
     .pd-hero-inner  w=1440 bg=**白**          ← 白块 1
     .pd-content     w=1040 bg=**白**          ← 白块 2
     .pd-aside       w=360  bg=**白**          ← 白块 3
   ⇒ 宽屏上就是「三个白块浮在灰底上」= 他说的"块状阴影"。
   ★ 首页的做法（`.hm` w=1680 铺满白 + `.hm-inner` 限宽 1440）是同一个同构解法：
     外层铺满白底，限宽交给内层。这里照首页同构 —— 只补 `.pd` 的白底，
     `.pd-hero` / `.pd-body` **本来就有** `max-width:1440; margin:0 auto`（见下），
     所以限宽一个像素都不用动。
   ★ 几何中性：`.pd` 的背景铺满 padding box（含左右 30px），
     1440 档下 `.pd` 宽就是视口宽 ⇒ 背景色之外**不改任何尺寸**。 */
.pd { padding: 0 30px 90px; background-color: var(--hs-white); }

/* ---- 第一屏 ---- */
.pd-hero { max-width: var(--hs-container); margin: 0 auto; padding: 20px 0 40px; }
.pd-hero-inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: 40px;
    background-color: var(--hs-white);
    padding: 50px 40px;             /* 对应老站 .y-cont padding:.5rem .4rem */
}

/* 左：图片（老站 .y-left 3.6rem = 360px） */
.pd-media { width: 360px; flex: 0 0 360px; display: flex; flex-direction: row-reverse; gap: 16px; }
.pd-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;            /* 老站 .y-img padding-top:100% */
    border: 1px solid var(--hs-line);
    background-color: var(--hs-white);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.pd-stage img { width: 100%; height: 100%; object-fit: contain; }
.pd-noimg { color: var(--hs-text-mute); font-size: 15px; padding: 20px; text-align: center; }

.pd-thumbs { width: 100px; flex: 0 0 100px; }
.pd-thumb {
    display: block; width: 100%; padding: 0; margin-bottom: 12px;
    border: 1px solid var(--hs-line-2); background: none; overflow: hidden;
    aspect-ratio: 1 / 1;
}
.pd-thumb img { width: 100%; height: 100%; object-fit: contain; }
.pd-thumb.is-active { border-color: var(--hs-blue); }

/* 右：信息（老站 .y-right 9.45rem = 945px） */
.pd-info {
    flex: 1 1 0;
    min-width: 0;
    max-width: 945px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-self: stretch;
}
.pd-head { padding-top: 5px; }

/* 产品名 —— 这里是 H1（老站被 logo 占用了，产品名只能当 H2） */
.pd-title {
    font-size: 26px;
    line-height: 1.38;
    color: var(--hs-text);
    margin-bottom: 6px;
    word-break: break-word;
}
/* 订购型号：老站只有基础型号，客户下单要的是带封装后缀的完整型号 */
.pd-ordercode { font-size: 15px; color: var(--hs-text-3); margin-bottom: 16px; }
.pd-ordercode-label { margin-right: 8px; }
.pd-ordercode-value { font-weight: 700; color: var(--hs-blue); }

/* 参数面板：视觉同老站 .y-tr/.y-td 的四列浅蓝块，语义换成 <dl> */
.pd-specs {
    display: flex;
    flex-wrap: wrap;
    background-color: var(--hs-bg);
    padding: 15px 10px;
    margin-bottom: 20px;
    font-size: 16px;
}
.pd-spec { width: 25%; padding: 5px 10px; line-height: 1.6; color: var(--hs-text-2); }
.pd-spec dt { display: inline; }
.pd-spec dd { display: inline; margin: 0; word-break: break-word; }
/* 中英标点按语言切换，老站英文页也用了全角冒号，这里顺手修掉 */
.pd-spec dt::after { content: '：'; }
.lang-en .pd-spec dt::after { content: ': '; }

/* 行动按钮（老站 y-car / y-consult / y-download / y-apply）
   —— 整组**靠左**（#102 修订，JACK 2026-09-18 定：原右对齐会与右侧固定的
      「侧边活动栏」(.sd) 在窄一点的视口下压在一起）。
      间距交给 gap，所以 .pd-btn 自己不再带 margin。 */
.pd-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 10px;
    padding-bottom: 20px;
}
/* ★ 2026-09-25 改（台账 #302=B / #303=A，JACK）：三枚 = 在线询价 / 索取规格书 / 申请样品。
   配色照抄列表页动作列 .cl-act（2026-09-21 #273 定稿）：
     · 唯一橙实心挂「在线询价」（一屏只强调一件事，#226=A 精神不变）；
     · 另两枚白底 + 1px 细灰边(--hs-line-3) + 蓝字(--hs-blue)；
     · hover = 蓝边 + 浅蓝底 + 蓝字（列表页同款，不是变蓝实心）。
   ★ 排版尺寸恢复 #302 更换前的字号（2026-09-25 JACK 复核反馈「按钮大小和字号有点小」）：
     font-size 16 / line-height 46 / padding 0 15px —— 内容（三枚/顺序/文案/配色）不动。
   ★★ 字重 700（2026-09-25 JACK 第二次复核「保持字号和高/宽，把字体加粗」）——
     与列表页动作列（.cl-acts > .cl-act，#288-⑤）同权重。
   原 -dl（规格书下载）/ -list（加入询价单）规则随模板删除（#302，判据同步：
   analysis/_pd_actions_geom.js 按三枚新契约更新）。 */
.pd-btn {
    display: inline-block;
    min-width: 130px;
    padding: 0 15px;
    margin: 0;
    text-align: center;
    font-size: 16px;
    font-weight: 700;
    line-height: 46px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    color: var(--hs-blue);
    border-radius: var(--hs-radius);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.pd-btn-quote { background-color: var(--hs-orange); border-color: var(--hs-orange); color: var(--hs-white); }

.pd-btn-quote:hover { background-color: var(--hs-orange-dark); color: var(--hs-white); border-color: var(--hs-orange-dark); }
.pd-btn-ds:hover,
.pd-btn-sample:hover { border-color: var(--hs-blue); background-color: var(--hs-blue-light); color: var(--hs-blue); }

/* 需索取时的提示：在 flex 按钮组里独占一行，跟着左对齐走 */
.pd-sheet-hint { flex: 0 0 100%; font-size: 14px; color: var(--hs-text-mute); margin: 0; text-align: left; }

/* ---- 第二屏 ---- */
.pd-body { max-width: var(--hs-container); margin: 0 auto; }
.pd-body-inner { display: flex; gap: 40px; align-items: flex-start; }

.pd-content { flex: 1 1 0; min-width: 0; background-color: var(--hs-white); padding-bottom: 45px; }
.pd-aside { width: 360px; flex: 0 0 360px; background-color: var(--hs-white); padding-bottom: 40px; }

/* 老站 .ya-top：标题下压一条 1px 阴影 + 标题文字下 3px 蓝线
   ★ #304-①（2026-09-25 JACK）：标题横线与栏内内容等宽 —— 线原来横贯 .pd-content
     全宽（968），而内容在 sec-body 的 40px 内距里（888）⇒ 线比内容两侧各宽 40。
     改用 margin 缩进（padding 保留，文字位置不动），线 = 内容宽 888，左右缘对齐。 */
.pd-sec-head { margin: 0 40px; padding: 0 0; box-shadow: 0 1px 0 0 var(--hs-line-2); }
.pd-sec-title {
    display: inline-block;
    position: relative;
    font-size: 22px;
    line-height: 70px;
    /* ★ 2026-09-20 改（台账 #225，JACK 选 C）：标题文字色 蓝 → 深灰。
       原因：首页定稿的区块标题 `.hm-h2` 是深灰无装饰线，产品页原来是
       「22px 蓝字 + 3px 蓝下划线」—— 那是老站 `.ya-top` 的样式（见上一行注释）。
       两者不构成同一套视觉语言。C 方案保留字号与蓝线、只换文字色属最小改动。
       蓝线保留（它是本页唯一的强调记号，与首页卡片 3px 蓝顶边同色同宽）。 */
    color: var(--hs-text);
    max-width: 100%;
}
.pd-sec-title::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 3px;
    background-color: var(--hs-blue);
}
/* 二级区块标题（规格书 / 完整规格参数，台账 #225=C 的实样形态）：
   与 .pd-sec-title 同一套（灰线 + 3px 蓝线），字号小一档、行高同比收窄。 */
.pd-sec-title--sub { font-size: 20px; line-height: 60px; }

.pd-sec-body { padding: 45px 40px; }
/* #304-④：规格书区顶距压到 34px（标题线→卡 = 34，原 45+40=85 的 40%，-60%）。 */
.pd-sec-body--sheet { padding-top: 34px; }
.pd-subtitle { font-size: 20px; color: var(--hs-text); line-height: 1.5; margin-bottom: 15px; }
.pd-text { font-size: 16px; color: var(--hs-text-2); line-height: 1.87; word-break: break-word; margin-bottom: 20px; }
.pd-text * { max-width: 100%; line-height: inherit; }
.pd-text img, .pd-text table { max-width: 100%; height: auto; }
.pd-text table { border-collapse: collapse; }
.pd-text table td, .pd-text table th { border: 1px solid var(--hs-line); padding: 6px 10px; }

/* 侧栏「相关应用」（#103）：技术社区文章列表。
   标题最多 4 行 —— EN 标题最长可到 110 字符，不限行会把侧栏拉得很长。 */
.pd-app-list { padding: 30px 40px 10px; }
.pd-app-item { margin-bottom: 22px; }
.pd-app-link {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 16px;
    line-height: 1.55;
    font-weight: 700;
    color: var(--hs-text);
    overflow-wrap: anywhere;
    transition: color .2s ease;
}
.pd-app-link:hover { color: var(--hs-blue); }
/* 应用标签（#105）：口径与社区列表页 .tf-tag.tf-tag-app 完全一致（蓝色浅底）。
   侧栏可用宽约 280px，用 flex-wrap 自然折行；长标签名靠 overflow-wrap 断词。 */
.pd-app-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.pd-app-tag {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--hs-radius);
    font-size: 13px;
    line-height: 1.6;
    background-color: var(--hs-blue-light);
    color: var(--hs-blue);
    overflow-wrap: anywhere;
}
.pd-app-date { display: block; margin-top: 6px; font-size: 13px; color: var(--hs-text-3); }
.pd-app-tags + .pd-app-date { margin-top: 8px; }
/* #315（2026-09-25 JACK）：标题去掉加粗（原 16px/700 显得太重）——字号不动，只回 400。 */
.pd-app-link { font-weight: 400; }
/* #315：默认显示 6 个，超出折叠（main.js §8 加/去 is-collapsed，无 JS 全量可见） */
.pd-app-list.is-collapsed .pd-app-item:nth-child(n+7) { display: none; }
.pd-app-more {
    display: block; margin: 0 40px 18px; padding: 0;
    border: 0; background: none;
    font-size: 14px; color: var(--hs-blue); cursor: pointer;
}
.pd-app-more:hover { text-decoration: underline; }

/* 完整规格参数表（首屏超过 12 条时补在这里） */
.pd-table { width: 100%; border-collapse: collapse; font-size: 16px; margin-bottom: 24px; }
.pd-table th, .pd-table td { border: 1px solid var(--hs-line); padding: 10px 14px; text-align: left; vertical-align: top; }
.pd-table th { width: 42%; background-color: var(--hs-bg); font-weight: 400; color: var(--hs-text-2); }
.pd-table td { color: var(--hs-text); }

/* ---- 规格书卡 + 原生折叠预览（#101 A，JACK 2026-09-18 定）----
   默认只渲染卡片、**不加载 PDF**；点 <summary> 才在同一页原地展开 iframe。
   原 `.pd-pdf`（iframe 直嵌）已撤掉 —— 它会把 Chrome 自带的 PDF 工具栏
   （1/9、79%、打印图标）画进页面，移动端还要下完整份 PDF 才显示。 */
.pd-sheet { margin-top: 0; }   /* #304-④：原 40，顶部空隙改由 --sheet 的 34px 统一给 */
.pd-sheet-card {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    border: 1px solid var(--hs-line);
    border-radius: var(--hs-radius);
    background-color: var(--hs-bg);
}
.pd-sheet-ico {
    flex: 0 0 auto;
    width: 42px; height: 52px; line-height: 52px;
    text-align: center;
    font-size: 12px; font-weight: 700; letter-spacing: .5px;
    color: var(--hs-white); background-color: #d53b30;
    border-radius: 4px;
}
.pd-sheet-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.pd-sheet-name { font-size: 16px; font-weight: 700; color: var(--hs-text); overflow-wrap: anywhere; }
.pd-sheet-sub { font-size: 14px; color: var(--hs-text-3); }
.pd-sheet-dl {
    flex: 0 0 auto; min-width: 108px;
    text-align: center; font-size: 15px; line-height: 40px;
    color: var(--hs-white); background-color: var(--hs-blue);
    border-radius: var(--hs-radius); text-decoration: none;
    transition: background-color .2s ease;
}
.pd-sheet-dl:hover { background-color: var(--hs-blue); color: var(--hs-white); }

/* #355（2026-09-26）：规格书卡下小链 → /downloads 枢纽页（全站循环入口④） */
.pd-sheet-more {
    display: inline-block;
    margin-top: 8px;
    font-size: 13px;
    color: var(--hs-blue);
    text-decoration: none;
}
.pd-sheet-more:hover { text-decoration: underline; }

/* 折叠预览：details/summary 原生元素，无 JS 也可用，收起时 iframe 不会发请求 */
.pd-fold { margin-top: 12px; border: 1px solid var(--hs-line); border-radius: var(--hs-radius); }
.pd-fold-sum {
    position: relative;
    padding: 0 46px 0 18px;
    line-height: 48px;
    font-size: 15px;
    color: var(--hs-blue);
    cursor: pointer;
    list-style: none;
    user-select: none;
}
.pd-fold-sum::-webkit-details-marker { display: none; }
.pd-fold-sum::after {
    content: '';
    position: absolute; right: 20px; top: 50%;
    width: 9px; height: 9px; margin-top: -7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform .2s ease, margin-top .2s ease;
}
.pd-fold[open] .pd-fold-sum::after { margin-top: -2px; transform: rotate(225deg); }
/* #304-⑤：默认展开 ⇒ summary 文案随状态切换（收起态显「展开预览」、展开态显「收起预览」） */
.pd-fold-when-open { display: none; }
.pd-fold[open] .pd-fold-when-closed { display: none; }
.pd-fold[open] .pd-fold-when-open { display: inline; }
.pd-fold-view { border-top: 1px solid var(--hs-line); }
/* ★ #306（2026-09-25 JACK）：预览视口 = A4 长宽比、一次展示一页。
   实现走自托管 PDF.js（main.js §6）：canvas 按「容器宽/页宽」精确缩放渲染单页，
   页面高度天然 = 宽 × √2，不需要写死任何高度（原 iframe 700px / 窄档 440px 退役；
   Chrome 内置查看器 fragment 参数三版实测不可靠，弃用）。 */
.pd-pdf-stage { background-color: var(--hs-bg); text-align: center; min-height: 180px; }
.pd-pdf-canvas { display: inline-block; max-width: 100%; }
.pd-pdf-nav { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 10px 0; border-top: 1px solid var(--hs-line); }
.pd-pdf-btn {
    padding: 5px 14px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    color: var(--hs-blue);
    font-size: 13px;
    line-height: 20px;
    border-radius: var(--hs-radius);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}
.pd-pdf-btn:hover { border-color: var(--hs-blue); background-color: var(--hs-blue-light); color: var(--hs-blue); }
.pd-pdf-btn:disabled { opacity: .4; cursor: default; }
.pd-pdf-btn:disabled:hover { border-color: var(--hs-line-3); background-color: var(--hs-white); color: var(--hs-blue); }
.pd-pdf-ind { font-size: 13px; color: var(--hs-text-2); }

.pd-aside-cta { padding: 10px 40px 0; }
.pd-aside-cta .pd-btn { margin: 10px 0; width: 100%; }

/* ==========================================================================
   品类页
   ========================================================================== */
/* ★ #253-①：`.cl` 补白底。原来它没有背景色 ⇒ 透出 body 的灰底 `--hs-bg`，
   于是整页变成「白 · 白 · 灰(筛选区) · 白 · 白」的斑马条，和首页的
   「整片白底 + 一条内容列」不是一回事（首页靠 `.hm` 这个铺满视口的白底容器）。
   加上白底后，两侧不再露出灰边，页型与首页同构：
   一片白 + 内部一块灰的筛选面板 + 一条细线段落分隔。 */
/* ★★★ 2026-09-24（JACK 第 1 条）：「产品页的背景和首页保持一致，不要有块状阴影」。
   根因（1680 档实测）：**首页的白底是"铺满视口 + 内层限宽"，产品页的白底却是"只有 1440 居中"** ——
     · 首页 `.hm`   w=**1680**（铺满）bg 白；限宽交给内层 `.hm-inner { max-width:1440; margin:0 auto }`
     · 列表页原来 `.cl` w=**1440**（居中）⇒ 宽屏上**两侧各露出 body 灰底**（1680 时左右各 120px），
       再加面包屑条透明、筛选区自带宽灰底 ⇒ 整页读成「白块 + 灰块」= 他说的"块状阴影"。
   ⇒ 照首页同构改：**`.cl` 只负责白底铺满，限宽下放给直接子元素**。
   ★ 几何中性：`.cl` 宽度 ≥1440 时子元素恒等于 1440 居中，与原布局**逐像素相同**；
     <1440 时子元素 = 视口宽，也与原来相同（因为原来 `.cl` 就是 min(视口,1440)）。 */
.cl {
    padding: 0 0 90px;
    background-color: var(--hs-white);
}
/* #297 视觉总量口径：一览块下方到页脚的 90px 全来自这里。
   有「参数档位一览」的品类页挂 .cl-has-ov（模板条件类），
   按 JACK「下-40%」收成 54px；其它页型不动。 */
.cl-has-ov { padding-bottom: 54px; }
/* 限宽只加在直接子元素上 —— `.cl` 的 4 个直接子元素是
   `.cl-head` / `.cl-tabs` / `.cl-filter` / `.cl-body`（全仓没有 `.cl >` 选择器，已核）。 */
.cl > * {
    max-width: var(--hs-container);
    margin-left: auto;
    margin-right: auto;
}
.cl-head { background-color: var(--hs-white); padding: 0 40px 24px; }   /* #289-① 后只剩简介，顶距归零（分类行在上） */
.cl-intro { font-size: 16px; color: var(--hs-text-2); line-height: 1.87; max-width: 1000px; }
.cl-intro > :last-child { margin-bottom: 0; }

/* 表头「类别」区
   对应老站 /product.html 的 .classify（#cat_list_box / #cat_list2_box）：
   第一行一级分类固定，第二行随选中项变化的二级分类。

   用行内 tab 而不是下拉菜单，是为内链服务：分类是全站最重要的内链骨架，
   全部留在 HTML 里让爬虫一次抓全。老站这两行是 AJAX 塞进去的，HTML 里
   根本不存在 —— 这是老站分类内链几乎为 0、分类词全没排上的直接原因。 */
.cl-tabs { background-color: var(--hs-white); padding: 26px 40px 24px; }   /* #289-①：分类行上移成首块，补回顶距 */
.cl-tabs-row { display: flex; gap: 16px; padding: 10px 0; border-top: 1px dashed var(--hs-line-2); align-items: center; }
.cl-tabs-row:first-child { border-top: 0; padding-top: 0; }
.cl-tabs-tip { flex: 0 0 100px; font-size: 15px; color: var(--hs-text-3); line-height: 32px; }   /* 100px：容纳「Device type」，两行左缘对齐 */
/* #316（2026-09-25 JACK）：类别之间加「|」分隔 + 空距大一点+20% ——
   项与分隔符空隙 12px（sep 是独立 flex 项，类别间总空 ≈ 12+|+12 ≈ 24×1.2）。 */
.cl-tabs-list { display: flex; flex-wrap: wrap; gap: 8px 12px; flex: 1 1 auto; min-width: 0; }
.cl-tabs-sep { color: var(--hs-text-3); line-height: 32px; user-select: none; }
/* #289-②（2026-09-24 JACK）：一级分类加粗。#316 起二级与一级**完全同构**
   （模板直接用 .cl-tab，卡式 .cl-subtab 已退役）。 */
.cl-tab { font-size: 15px; color: var(--hs-text-2); line-height: 32px; font-weight: 700; border-bottom: 2px solid transparent; }
.cl-tab:hover { color: var(--hs-blue); }
.cl-tab.is-active { color: var(--hs-blue); border-bottom-color: var(--hs-blue); font-weight: 700; }
/* #316（2026-09-25 JACK）：二级分类与一级同构，卡式（1px 边 + 2.3px 蓝顶边，
   #290-③/#293/#294）整组退役；容器只保留 flex 布局职责，间距同一级。 */
.cl-subtabs { display: flex; flex-wrap: wrap; gap: 8px 12px; flex: 1 1 auto; min-width: 0; }
/* #316 追拍（2026-09-25 JACK）：二级**不加粗**（active 靠蓝字+蓝底线区分）。 */
.cl-subtabs .cl-tab,
.cl-subtabs .cl-tab.is-active { font-weight: 400; }
/* 纯分组分类（无直属型号，直属型号为 0）：它是导航入口而不是落地页，
   视觉上弱一档，但仍可点 —— 客户点进来要能看到该分组下的器件类型。 */
.cl-tab.is-group { color: var(--hs-text-3); }
.cl-tab.is-group:hover { color: var(--hs-blue); }
.cl-tabs-note {
    margin: 10px 0 0;
    padding: 12px 16px;
    font-size: 14px;
    line-height: 1.8;
    color: var(--hs-text-3);
    background-color: var(--hs-blue-light);
    border-radius: var(--hs-radius);
}

/* 排序 + 型号搜索同一行：左排序、右 Search by Part No.（老站形态）。
   ★ 由「仅在有筛选/多页时显示」改为**常显** —— 搜索框必须常驻，
     否则单页品类里客户没法按型号找料（老站也是常显的）。 */
.cl-toolbar { background-color: var(--hs-white); padding: 0 40px 20px; }
.cl-toolbar-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    border-top: 1px solid var(--hs-line-2); padding-top: 20px;
}
.cl-sort { display: flex; gap: 8px; }
.cl-sort-item { padding: 5px 14px; font-size: 15px; color: var(--hs-text-2); border: 1px solid var(--hs-line-3); }
.cl-sort-item.is-active { background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white); }

/* 排序条右侧的两个小控件：每页条数 + 型号搜索。
   ★ 条数刻意做成**轻量纯文字**（当前项蓝色加粗），不跟排序条的描边胶囊抢重量 ——
     一屏只强调一件事：这一屏的主角是型号列表，不是这两个辅助控件。 */
.cl-tools { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.cl-per { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.cl-per-label { color: var(--hs-text-mute); }
.cl-per-item { color: var(--hs-text-3); }
.cl-per-item:hover { color: var(--hs-blue); }
.cl-per-item.is-active { color: var(--hs-blue); font-weight: 700; }

/* 型号搜索：GET 提交进同一个 action，带上当前筛选、排序与条数的 hidden
   ⇒ 搜型号不会把已凑好的参数条件丢掉。
   放大镜是纯 CSS 画的（内联 SVG 全仓唯一合法出处是 AdIcon，这里不新开一个）。 */
.cl-search { position: relative; display: flex; align-items: center; }
.cl-search-input {
    width: 250px; max-width: 100%;
    padding: 7px 38px 7px 12px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; color: var(--hs-text);
}
.cl-search-input::placeholder { color: var(--hs-text-mute); }
.cl-search-input:focus { outline: none; border-color: var(--hs-blue); }
.cl-search-btn {
    position: absolute; right: 0; top: 0; bottom: 0;
    width: 36px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; border-left: 1px solid transparent;
    background: none; cursor: pointer;
    color: var(--hs-text-mute);
}
.cl-search-btn:hover { color: var(--hs-blue); }
.cl-search-ico {
    position: relative;
    width: 12px; height: 12px;
    border: 2px solid currentColor;
    border-radius: 50%;
}
.cl-search-ico::after {
    content: ''; position: absolute; right: -4px; bottom: -4px;
    width: 6px; height: 2px;
    background-color: currentColor;
    transform: rotate(45deg);
}

/* ---- 筛选条（横向 chips + 整幅取值面板） ----
   原方案是左侧 250px 竖栏：宽屏下白占一列产品位，而客户只在选型那一刻看它。
   改成横条后产品区拿回全宽；取值面板从条下沿整幅铺开，60 个档位也放得下。
   面板用绝对定位脱流 —— 展开时不会把产品列表往下推，浏览位置不跳。 */
/* 8 列平铺筛选面板（台账 #233=A + #242=A）
   --------------------------------------------------------------------------
   形状依据：老站就是「一整块平铺、勾完点提交」，不是逐项点击即生效。

   为什么从「胶囊 <details>」改成平铺：
     · 折叠把「有哪些维度、每维几个取值」藏起来，客户要先点开 8 次才看得见全貌，
       而选型的真实动作是"同时定电压 + 封装 + 功率"——需要一眼看全；
     · <details> 里的取值是链接、点一个就整页重载（URL 立刻变成筛选态），
       凑 3 个条件要刷 3 次页、试错成本高；
     · 换成原生表单后无 JS 可用性反而更好：复选框 + submit 是浏览器原生行为。

   ★ 刻意不做 position:sticky —— 吸顶条会在整页浏览时永久遮住一屏产品位，
     主流电商的筛选条也都不吸顶，收益不抵遮挡。 */
.cl-filter {
    background-color: var(--hs-bg);
    border-top: 1px solid var(--hs-line-2);
    border-bottom: 1px solid var(--hs-line-2);
    padding: 18px 40px 14px;
}
.cl-filter-bar { display: block; }
.cl-filter-title {
    margin: 0 0 12px;
    font-size: 14px; font-weight: 700; color: var(--hs-text);
}

/* #253-③：筛选面板 —— 一条 1px 细线分隔，不空缝。
   #295（2026-09-24 JACK 修订，覆盖 #253-③ 的「换行 + 摊满」口径）：
     · **不再换行**：维度框一整排排开，装不下时**整行下方出左右滚动条**，
       筛选时直接横向滚，不用点 More 再勾（More 本身也已删）；
     · 装得下时 `flex-grow:1` 仍把余量摊回去填满整幅宽度（`flex-shrink:0`
       必须同时给：否则 nowrap 下框会被压瘪、滚动条出在框内而不是行底）；
     · 滚动条：**2px 细条**（§102 销账三 #295-②：3→2）+ `#ededed` 浅灰轨道照老站 `.my-scrollbar` 的几何；
       **滑块不用蓝**——#298（2026-09-25 JACK）：滑块/端头箭头一律灰（#c1c1c1，
       Chrome 原生滑块灰），端头箭头按钮显式禁掉（Windows Chrome 会渲染出来）。
   实现要点：
     · `gap: 1px` + 容器背景色 = 线色 ⇒ 1px 细线，不空缝；
     · `min-width: 0` 保留：长值换行（overflow-wrap:anywhere），不撑破框。 */
.cl-facets {
    display: flex;
    flex-wrap: nowrap;
    gap: 1px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-line-3);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-color: #c1c1c1 #ededed;
    scrollbar-width: thin;
}
.cl-facets::-webkit-scrollbar { width: 2px; height: 2px; }
.cl-facets::-webkit-scrollbar-thumb { border-radius: 1px; background: #c1c1c1; }
.cl-facets::-webkit-scrollbar-track { border-radius: 1px; background: #ededed; }
.cl-facets::-webkit-scrollbar-button { display: none; }
.cl-facet {
    flex: 1 0 auto;              /* 装得下：grow 摊满；装不下：绝不 shrink，行滚 */
    min-width: 0;
    padding: 12px 14px 14px;
    background-color: var(--hs-white);
}
/* 一列的标题：参数名 + 单位 + 已选角标。
   ★ 不用大写变形（uppercase）：中文参数名没有大小写，英文名里 `VBR(V)(Min)`
     这类缩写大写后更难认。
   ★ 原 padding-right:40px 是给右上角 More 留位的——More 已删（#295），撤掉。
   #314（2026-09-25 JACK）：表头文本**居中** + 表头语汇 = 通框浅灰底条 +
   1px 底分隔线（负边距把底条通到框缘）。同时它兼任前台拖拽把手
   （main.js §7，cursor:grab），只拖表头动框、勾选值不受干扰。
   追拍①：底条用 #ededed——与滚动条轨道同款，比 --hs-bg 再淡一档。 */
.cl-facet-name {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 4px;
    justify-content: center;
    margin: -12px -14px 10px;
    padding: 9px 10px 8px;
    border-bottom: 1px solid var(--hs-line-3);
    background-color: #ededed;
    font-size: 13px; font-weight: 700; color: var(--hs-text);
    line-height: 1.4;
    cursor: grab;
}
.cl-facet-name:active { cursor: grabbing; }
/* 拖拽状态（main.js §7）：源框半透明，悬停目标框左侧 3px 蓝条指示落点 */
.cl-facet.is-dragging { opacity: 0.45; }
.cl-facet.is-drop-target { box-shadow: inset 3px 0 0 var(--hs-blue); }
.cl-facet-unit { color: var(--hs-text-mute); font-size: 12px; font-weight: 400; }
/* 已选角标：一眼看出哪个维度生效了，不用逐列数。
   ★ 这不是「每个取值有多少型号」的计数（那个按 #250-⑧ 去掉了），
     是「本维勾了几项」——筛选面板很长，滚下去之后仍要知道自己勾了什么。 */
.cl-facet-picked {
    min-width: 17px; height: 17px; line-height: 17px;
    padding: 0 5px; border-radius: 9px;
    background-color: var(--hs-blue); color: var(--hs-white);
    font-size: 11px; font-weight: 700; text-align: center;
}

/* #295（2026-09-24 JACK）：框内上下滚动区 —— 替代「More」折叠。
   · max-height: 160.8px = 取值行高 26.8px × 6 行（与改前 FACET_HEAD=6 的
     可见行数完全一致，实测 _facet_row_h.js）；
   · 滚动条：3px 细条 + #ededed 轨道（几何照老站）；**滑块灰 #c1c1c1 不用蓝**（#298）；
   · **取值少于窗口时垂直居中**：flex 列容器 + 子项上下 auto 外边距——
     余量为正时居中、为负（要滚）时 auto=0 正常从顶滚，不用 justify-content:center
     （那个会把溢出内容的顶部裁掉，是经典坑）。 */
.cl-facet-scroll {
    display: flex; flex-direction: column;
    max-height: 160.8px;
    overflow-y: auto;
    scrollbar-color: #c1c1c1 #ededed;
    scrollbar-width: thin;
}
.cl-facet-scroll::-webkit-scrollbar { width: 2px; height: 2px; }
.cl-facet-scroll::-webkit-scrollbar-thumb { border-radius: 1px; background: #c1c1c1; }
.cl-facet-scroll::-webkit-scrollbar-track { border-radius: 1px; background: #ededed; }
.cl-facet-scroll::-webkit-scrollbar-button { display: none; }

.cl-facet-values { list-style: none; margin: auto 0; padding: 0; }
.cl-facet-values li { break-inside: avoid; }
.cl-facet-value {
    position: relative;             /* 原生 checkbox 绝对定位的定位上下文 */
    display: flex; align-items: flex-start; gap: 7px;
    padding: 3px 4px;
    border-radius: var(--hs-radius);
    font-size: 13px; color: var(--hs-text-2);
    cursor: pointer;
}
.cl-facet-value:hover { background-color: var(--hs-bg); color: var(--hs-blue); }
/* ★ 视觉隐藏但**保留在无障碍树与 Tab 序列里** —— 不要用 display:none /
   visibility:hidden：那会让键盘 Tab 跳过它、读屏读不到，等于把控件删了。
   1px + opacity:0 是唯一既看不见又可聚焦的做法。 */
.cl-facet-input {
    position: absolute; left: 4px; top: 5px;
    width: 1px; height: 1px; margin: 0; padding: 0;
    opacity: 0; cursor: pointer;
}
.cl-facet-box {
    flex: 0 0 14px; height: 14px; margin-top: 2px;
    position: relative;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
}
.cl-facet-input:checked + .cl-facet-box {
    background-color: var(--hs-blue);
    border-color: var(--hs-blue);
}
.cl-facet-input:checked + .cl-facet-box::after {
    content: ''; position: absolute; left: 4px; top: 1px;
    width: 3px; height: 7px;
    border: solid var(--hs-white); border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.cl-facet-input:focus-visible + .cl-facet-box {
    outline: 2px solid var(--hs-blue); outline-offset: 1px;
}
.cl-facet-label { flex: 1 1 auto; min-width: 0; word-wrap: break-word; overflow-wrap: anywhere; }
.cl-facet-input:checked ~ .cl-facet-label { color: var(--hs-blue); font-weight: 700; }

/* 「更多」折叠已删（#295，2026-09-24 JACK：More 换成框内上下滚动条），
   原 .cl-facet-rest / .cl-facet-rest-sum 规则一并撤掉（判据同步，铁律 #5）。 */

/* 面板底部：符合条件数 / 清除 / 确定。
   确定按钮是这一屏唯一的实心蓝（一屏只强调一件事）。 */
.cl-filter-foot {
    display: flex; align-items: center; gap: 12px;
    margin-top: 14px; padding-top: 12px;
    border-top: 1px solid var(--hs-line-3);
}
.cl-filter-count { font-size: 13px; color: var(--hs-text-3); }
.cl-filter-count b { color: var(--hs-text); }
.cl-filter-spacer { flex: 1 1 auto; }
.cl-filter-clear {
    padding: 7px 16px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 13px; color: var(--hs-text-3);
}
.cl-filter-clear:hover { color: var(--hs-blue); border-color: var(--hs-blue); }
.cl-filter-apply {
    padding: 8px 28px;
    border: 1px solid var(--hs-blue);
    background-color: var(--hs-blue);
    color: var(--hs-white);
    font-size: 14px; font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}
.cl-filter-apply:hover { background-color: var(--hs-blue); border-color: var(--hs-blue); }
/* 无 JS 时这条路必须走得完：按钮原本就是 submit，浏览器原生发 GET，无需脚本兜底 */

/* 已选条件标签：整行另起，跟面板分开 */
.cl-tags {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    margin-top: 12px;
}
.cl-tags-label { font-size: 12px; color: var(--hs-text-mute); }
.cl-tag {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px;
    background-color: var(--hs-blue-light);
    border: 1px solid var(--hs-blue-light);
    border-radius: var(--hs-radius);
    font-size: 13px; color: var(--hs-blue);
}
.cl-tag:hover { background-color: var(--hs-blue); color: var(--hs-white); border-color: var(--hs-blue); }
.cl-tag-facet { color: var(--hs-text-3); font-size: 12px; }
.cl-tag:hover .cl-tag-facet { color: rgba(255, 255, 255, .8); }
.cl-tag-x { font-size: 14px; line-height: 1; }
.cl-tags-clear { margin-left: 4px; font-size: 13px; color: var(--hs-text-3); text-decoration: underline; }
.cl-tags-clear:hover { color: var(--hs-blue); }

.cl-filter-note { margin: 10px 0 0; font-size: 14px; color: var(--hs-text-3); }


.cl-body {
    padding: 30px 40px 40px;
    background-color: var(--hs-white);
}
.cl-main { min-width: 0; }

/* 死代码清理（2026-09-25 JACK）：原卡片网格 .cl-body .cl-grid 整组删除 ——
   列表早改成 .cl-row 表格行布局，网格规则无任何模板引用（_orphan_css.py 实扫）。 */
.cl-body .cl-pager { padding: 30px 0 0; }
.cl-body .cl-toolbar { padding: 0 0 20px; }
.cl-body .cl-empty { padding: 50px 20px; }

/* ---- 参数档位一览（GEO 用：真 <table>，机器可读） ----
   ★ #258：整块用原生 `<details>` 包起来、默认收起（JACK：「做隐藏但保留 AI/GEO 读取」）。
   收起时只剩这一行标题（原来铺开 942px），**内容仍完整在 HTML 源码里** ⇒ 爬虫/AI 照读。 */
.cl-overview {
    background-color: var(--hs-white);
    padding: 0 40px;          /* 上下内边距交给 summary 与 grid 各自管 */
    /* #297 视觉总量口径：jump pb 40→10（见 .cl-jump）、本块 margin 12→4、
       sum pt 16→10 ⇒ 上方视觉 149→约 105（-30%）。 */
    margin-top: 4px;
}
.cl-overview-sum {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 10px 0 12px;     /* #297 视觉总量口径：上 16→10（见 .cl-overview）、下 12 */
    cursor: pointer;
    list-style: none;         /* 去掉原生三角，改用自定义箭头 */
}
.cl-overview-sum::-webkit-details-marker { display: none; }
.cl-overview-sum::after {
    content: '▾';
    flex: 0 0 auto;
    color: var(--hs-blue); font-size: 14px;
}
.cl-overview[open] .cl-overview-sum::after { content: '▴'; }
/* #296-①（2026-09-24 JACK）：一览标题改**链接样式**——logo 蓝 + 下划线，点击开合，
   默认仍折叠（#258 的 <details> 机制不动，只换 summary 的皮）。
   字号 22px → 15px（链接就是正文字号；22px 蓝下划线不像链接，像报错标题）。
   hover 反馈 = 去下划线（同原生链接习惯）。 */
.cl-overview-title {
    margin: 0;
    font-size: 15px; font-weight: 400; color: var(--hs-blue);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}
.cl-overview-sum:hover .cl-overview-title { text-decoration: none; }
.cl-overview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 24px 30px;
    padding-bottom: 24px;     /* #297：展开态下方 40→24（−40%，与折叠态同比例） */
}
.cl-overview-item { min-width: 0; }
.cl-overview-attr {
    font-size: 15px; color: var(--hs-blue);
    margin-bottom: 10px; padding-bottom: 6px;
    border-bottom: 2px solid var(--hs-blue-light);
}
.cl-overview-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.cl-overview-table th, .cl-overview-table td {
    padding: 5px 8px; text-align: left;
    border-bottom: 1px solid var(--hs-line-2);
}
.cl-overview-table th { font-weight: 400; color: var(--hs-text-mute); font-size: 12px; background: var(--hs-bg); }
.cl-overview-table td:last-child, .cl-overview-table th:last-child { text-align: right; width: 70px; color: var(--hs-text-3); }
.cl-overview-table td:first-child { color: var(--hs-text-2); word-break: break-word; }


.cl-pager { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; background-color: var(--hs-white); padding: 0 40px 40px; }
.cl-page {
    min-width: 40px; padding: 0 12px; text-align: center; line-height: 38px;
    border: 1px solid var(--hs-line-3); font-size: 15px; color: var(--hs-text-2);
}
.cl-page:hover { border-color: var(--hs-blue); color: var(--hs-blue); }
.cl-page.is-current { background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white); }
/* 行式表格（台账 #228 定稿：Picture | Part No. | Specifications | Action）
   --------------------------------------------------------------------------
   为什么从「48 张卡片」改成行式表格：
     · 卡片一屏只能放 6~8 个型号，且**一个参数都没有**（只有图 + 型号 + 封装 chip）——
       客户要选型必须逐个点进详情页，一页 48 次点击才能比出两条的差别；
     · 选型的真实动作是"横着比"：同一列的电压、电流、封装对齐，差异一眼看出来；
     · 老站就是行式表格，客户的肌肉记忆在这里（#228 已定稿）。

   列宽：图 128 / 型号 240 / 参数自适应（内容自己封顶 580）/ 动作 190。
   参数格子内部再铺 3 列 —— **DOM 顺序 = 扫视顺序**，CSS 只负责分行（铁律 #10）。 */
.cl-list { background-color: var(--hs-white); }
.cl-list-head,
.cl-row {
    display: grid;
    /* ★★★ 列宽 = 老站列表行**实测**的恒定比例（`#259`）。
       ★ 净室声明（照抄的边界，必须写在代码里）：
         这里搬的**只有「比例」这一个客观测量值**，没有搬老站任何代码、类名、类样式、
         配色值、字号体系、圆角或图片。视觉皮肤 100% 走新站自己的设计系统（`main.css :root`
         变量 + 四语法），并与已定稿封存的首页保持一致。
         理由：结构与几何比例属**功能性/通用表达**，不受著作权保护；而模板的视觉皮肤
         （配色/图标/字体/装饰）才是权利归属存疑的部分 ⇒ 结构照老站，皮肤照自家首页。
       老站列表行在 1440 / 1024 / 768 三档实测（浏览器渲染尺寸，非源码）：
         视口   行宽   图格    型号格   参数格   动作格   行高
         1440   1080   174     194      438      240      195
         1024    768   124     138      312      171      181
          768    600    97     108      244      133      142
       换算成**占行宽的比例，三档完全一致**（这才是老站排版的真身）：
         图 16.13% ｜ 型号 17.98% ｜ 参数 40.60% ｜ 动作 22.20% ｜ 右侧余 3.09%
       ⇒ 格子宽度与视口无关，只有比例。所以这里写百分比，不写像素。
       ★ 顺带治掉两个真 bug（改前是 `128px 240px minmax(0,1fr) 190px` + `gap: 0 18px`）：
         · 1440 档参数列被 `1fr` 撑到 666，9 个短参数摊成 3 列 × 182 ⇒ 每列只有 ~85px 的字、
           右边空 97 ⇒ 这就是"**参数分布散**"的真根因（上一轮给它加 `max-width:580`
           只是把症状挪了个位置，没治列本身）。
         · 768 档固定像素列（128+240+190）+ 3 个 18px gap = 692 > 可用 686 ⇒
           **横向溢出**，且参数列被 `minmax(0,1fr)` 压到 **80px、三列各 16px 完全不可读**。
           百分比列不会溢出（合计 96.91% < 100%）⇒ bug 自动消失。
       ★ `gap: 0`：老站格与格之间没有间距（实测格宽首尾相接），留白全靠**格内 padding** ——
         这也是"一条细线分隔、不要有空白"那条反馈的同一条语法。 */
    /* ★★★ 2026-09-24 第三次改（`#292`，JACK 直接给口径）：
       列宽改为 **图片 15% ｜ 型号 20% ｜ 参数 40% ｜ 动作 auto**。
       ★ 老站实测比例（16.13/17.98/40.60/22.20，`#259`）自此**作废** —— 授权编号 `#292`，
         净室声明照旧：此前搬的只有「比例」这一个测量值，现由 JACK 亲自给定新值，非自创。
       auto = 25% 尾差仍并入动作列，按钮组贴右不变 ⇒ 左右留白继续对称。 */
    /* Keep the 114px image frame and 12px clearance from the model on tablets. */
    grid-template-columns: minmax(126px, 15%) 20% 40% auto;
    gap: 0;
    /* ★★★ 2026-09-21 JACK：「我依然觉得这个设计和老站差很多」—— 上一轮我只搬了「列的宽度比例」，
       没搬「列里面的东西长什么样」。比例对 ≠ 观感像。本轮的修正都在下面各元件里，逐条照老站实测：
         · 行内边距 16 → **22px**（老站 22.5）⇒ 行高 180 → 194 ≈ 老站 195
         · `align-items` start → **center**（老站 `za-item` 是 center）——
           老站图/型号/参数都是相对那一列 150px 高的按钮组**垂直居中**的，
           新站原来全部顶对齐，这是"看着不一样"的一大来源
        ★ 老站版心 1080（左右各 180px 白）—— **刻意不搬**：
          新站首页 `.hm-sec` 内容宽 1288、列表页 `.cl-row` 内容 1278，本来就一致；
          收窄到 1080 会和已定稿封存的首页打架（JACK 自己定的"公共区域必须与首页一致"）。
          老站那 180px 大留白是它 1080 版心的**副产物**，不是能单独搬的东西。 */
    align-items: center;
}
.cl-list-head {
    align-items: center;
    padding: 10px 20px;
    background-color: var(--hs-blue);
    color: var(--hs-white);
    font-size: 13px; font-weight: 700;
}
/* ★★★ 2026-09-24（JACK 第 3 条）：「型号 part No. 和 规格描述 specification **靠左**」
   --------------------------------------------------------------------------
   这条**覆盖** `#274 = 甲`（那个"三个列名各在本列居中"的做法）。他看过实际页面后
   要求把**这两个**列名改回贴左 —— 注意他没提 Picture，因为 Picture 那格的内容
   （封装照）**本来就是居中**的，列名跟着居中才叫对齐。

   1440 档实测（`analysis/_cl_align_probe.js`，量的是**字形盒**不是元素盒）：
     列名（改前，居中）       列内容（一直是贴左）        左缘差
     Picture      glyph L=141.0   图 居中（列 60.0→266.1）
     Part No.     glyph L=356.1   .cl-part a L=**266.1**     90.0  ← 对不上
     Specifications glyph L=711.3 首个子列  L=**495.9**    215.4  ← 对不上得更远
   改成 Part No. / Specifications 贴左后，列名左缘 ⇒ **266.1 / 495.9**，
   与列内容的左缘**逐像素相等** ⇒ 表头与数据成一条竖线。Picture 保持居中不动。

   ★ 为什么必须逐格写选择器、而不是把 `text-align:left` 写在 `.cl-list-head` 上：
     `text-align` 是**继承属性**，写在容器上会一路传进展开的询价单面板
     （面板是第 4 格的子元素）—— 里面的大标题、右下角计数、空态说明文会全部
     变成左对齐，那是个真 bug（`#274` 时就踩过这个坑）。
     ⇒ 只打 `.cl-cell-pic` 与 `.cl-cell-name`/`.cl-cell-spec` 两个纯文字格；
       第 4 格是 flex 容器，`justify-content` 管按钮，`text-align` 本来也管不到它。 */
.cl-list-head .cl-cell-pic,
.cl-list-head .cl-cell-name,
.cl-list-head .cl-cell-spec { text-align: left; }   /* #292：图片列回贴左，Picture 列名同步（三列名全贴左） */
/* ★★ 表头第 4 格 = 询价单入口（`#272`，原位顶掉「Action」这个列名）
   --------------------------------------------------------------------------
   ① `position: relative` 是给展开面板当定位基准的（面板 `right:0; top:100%`）。
      它**没有 z-index**，所以不会创建层叠上下文 —— 面板的 `z-index` 因此落在
      根上下文里，才能盖住后面那些未定位的 `.cl-row`（表头在 DOM 里排在行的前面，
      不抬 z-index 的话面板会被行盖住）。
   ② 覆盖 `.cl-cell-act` 的竖排：这里只有一枚按钮，应当横向居中于表头行高。
   ③ 按钮**拉满整格**（`#276 = 乙`，2026-09-21 JACK 二次拍板；他先选过甲=居中，随后改乙）。
      `.qt` 是 flex 项 ⇒ 先让它 `flex: 1 1 auto` 吃掉整格，按钮再 `width: 100%`。
      1440 档：按钮从 141px 变成 **283.7px**，左右缘与下面 48 行的动作块**严格对齐**
      （`.cl-acts` 也是 283.7，同一条列宽比例 ⇒ Δ 应 ≈0，由 `_qt_geom.js` 的
      `btnVsActsL`/`btnVsActsR` 兜着）。
      ★ 连带的好处：展开面板 `right: 0` 现在是锚在**整格右缘**（1298.5），
        不再向右探出格子；面板左边到 978.5，整块落在参数列右半，比居中态更整齐。

   ========================================================================== */
.cl-list-head .cl-cell-act-head {
    position: relative;
    /* `#276 = 乙`：按钮拉满整格，所以这里的 `justify-content` 已经没有视觉作用
       （`.qt` 被 flex 撑满，撑满的东西居中与贴左等价）。保留 `center` 是为了
       **万一以后有人把 `.qt` 的 `flex` 撤掉**，它会退回"居中"而不是"贴左" ——
       两者都不算错，但居中比贴左更接近他前后两次选择的平均意图。
       展开面板是 `.qt` 的子元素、`right: 0` ⇒ 面板右缘 = 表头格右缘（1440 档 1298.5）。 */
    display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 0;
    /* ★★ 2026-09-24 第三次改：**撤掉**上一版的 18px 内距 —— 表头按钮现在由
       `.cl-list-head .qt` 自己定宽 248 并贴右缘，与行内按钮组同一套宽度和右缘。
       ★ 展开面板 `right:0` 锚本格 padding 盒右缘 = 格右缘 = 按钮右缘，仍对齐。 */
}
/* `.qt` 必须吃掉整格，否则 `width: 100%` 的按钮没有可撑的宽度基准 */
.cl-list-head .qt { flex: 0 1 auto; min-width: 0; width: min(248px, 100%); margin-left: auto; margin-right: 0; }
.cl-row {
    /* 老站行内边距实测 22.5px（1440 档）⇒ 行高 22.5×2 + 150(按钮组) = 195。
       新站原来 16px ⇒ 行高 180，比老站紧 15px，是"看着不一样"的一条。
       ★ #312（2026-09-25 JACK 选 A）：22 → 22.5，行高 159 → 160。 */
    padding: 22.5px 20px;
    border-bottom: 1px solid var(--hs-line);
    transition: background-color .15s ease;
}
.cl-row:hover { background-color: #fafcfe; }
.cl-cell { min-width: 0; }
/* ★★ #291-③（2026-09-24 JACK）：「规格参数内容…中间不要空行」——
   撤掉上一轮 #287② 的 `align-self: stretch`（参数格拉伸等高 + space-between 摊满）。
   ★ 这条同时也是表头错位的根因：stretch 连**表头**的规格格一起拉高，
     格内文字从顶格起排 ⇒「表头的规格参数没有上下居中，和其它字段不在一个水平位置」。
   撤掉后参数格回归 `.cl-row` 的 `align-items: center`，与图片/型号/按钮同一水平位。 */

/* 图片列：一页 48 行、同封装共用同一张封装照（实测 2085 个 TVS 型号只有 10 张图），
   所以照片会重复出现 —— 这是**封装照按封装复用**，外形是客户确认的第一眼信息，
   不是数据缺陷，不做"去重"（#243=A）。 */
.cl-pic {
    display: flex; align-items: center; justify-content: center;
    flex: 0 0 auto;
    /* #253-②：72 → 104。老站 98px —— 「图片小」是实物辨认的第一道障碍，
       外形是客户确认封装的第一眼信息，不能省。
       ★★ #291-②（2026-09-24 JACK）：104 → **114**（+10%）。
       ★★ #292（2026-09-24 JACK）：「图片/型号/参数列均为左对齐」—— 撤销 #291② 的
       格内居中，图盒**贴列左缘**（margin: 0）；垂直居中仍由 `.cl-row` 的
       `align-items: center` 承担。行高 159（114 + 22×2 内距 + 1 边线）。
       （Picture 列名同步贴左，见 `.cl-list-head .cl-cell-pic`。） */
    width: 114px; height: 114px;
    margin-left: 0; margin-right: auto;
    border: 1px solid var(--hs-line);
    background-color: var(--hs-white);
    overflow: hidden;
}
.cl-pic img {
    display: block;
    width: 100%; height: 100%;
    object-fit: contain;
    transform: translate(var(--cl-image-x, 0%), var(--cl-image-y, 0%)) scale(var(--cl-image-scale, 1));
    transform-origin: center;
}
.cl-pic-noimg {
    padding: 4px;
    font-size: 12px; font-weight: 700; color: var(--hs-text-mute);
    text-align: center; line-height: 1.3;
}

/* ★ 型号字号照老站：老站 `s18` 实测 **13.8px / line-height 20.7（比率 1.5）**。
   新站原来是 16px —— 比老站大 16%、行高也多 6px，整行看着就"重"了一档。 */
/* ★★ 2026-09-24（JACK 第 2.2 条「行距调大15%」）：行内文字的行高统一 ×1.15。
   1.5 → 1.725（14px 字 ⇒ 行高 21 → 24.15）、1.6 → 1.84（13px 字 ⇒ 20.8 → 23.92）。
   ★ 为什么只动 `line-height`、不动 `.cl-row` 的 padding：
     他这条挂在「2. 列表中样式」下面，前面 2.1 问的正是**参数区**的灰/黑字色
     ⇒ 同一语境 ⇒ 指的是**行内文字的行距**，不是"产品行与产品行之间"的距离。
     产品行的距离（padding 22px）是上一轮刚照老站实测（22.5px）定下来的，
     本轮不动，免得把刚对齐老站的数值又推歪。
   ★ 行高仍然不变（实测 149）：图片格 104 才是撑高那一格，
     三个文本块（型号 78 / 参数 71.8）都还远低于 104 ⇒ 只有文字内部松了。 */
.cl-part { display: block; font-size: 14px; font-weight: 700; line-height: 1.725; }
/* ★ #310（2026-09-25 JACK）：型号默认蓝 —— 引导用户点击进详情页
   （原：默认深灰、hover 才蓝；现在默认即蓝，hover 保持蓝色不回灰）。 */
.cl-part a { color: var(--hs-blue); }
.cl-part a:hover { color: var(--hs-blue); }
/* ★ 老站型号下面那行是**纯灰字**（`za-textbox`，12.9px，无底色无边框）。
   新站原来是个带底色的 chip（`background: var(--hs-bg)` + `padding: 1px 8px`）——
   一块灰底小方块在整行里非常显眼，是"看着不一样"最扎眼的一处。去掉底块，回到纯文字。
   ★★ 台账 `#279`（原 `#252`，2026-09-23 拍板「补，照老站」）已落地：
     这两行现在是老站那样的**两行带标签**（`Category:TVS diode` / `Package:SOD-123FL`）——
     ⇒ `#252` 原来挂着的"等定了再定色"也随之结清：老站这两行是 **`#333`（= `--hs-text`）**，
       与型号同色、只差字号。所以这里从 `--hs-text-2`(#555) 提到 `--hs-text`(#333)。
       实测老站：12.9px / line-height 20.64 / `#333`；本站取 13px / 1.6（同一行的取舍，非新偏差）。 */
.cl-meta { display: block; margin-top: 6px; font-size: 13px; color: var(--hs-text); line-height: 1.84; }
.cl-meta-i { display: block; }

/* 参数格：3 列网格，DOM 顺序 = 屏幕顺序
   ★ `#259`：列宽改成老站比例后，格子本身就是 40.60%（1440 档 ≈ 503px）；
     `#292` 起列宽改为 JACK 给定的 15/20/40/auto，参数格 40% = 511.2，来源变了结论不变 ——
     不再需要 `max-width` 封顶 —— 上一轮那个 `max-width: 580px` 是"列被撑宽"时代的补丁，
     现在列宽已由比例决定，留着反而会变成第二个宽度来源（JACK：「一个页面上有好多种
     不同宽度的框，是很低级的设计」）。删掉，只留一个宽度来源。
   ★ 实测老站参数格内部：431px 里 3 列各 144px、**列间 gap = 0**
     （靠列自身的空余分隔），行距也全靠 `line-height`。这里照抄 ⇒ `gap: 0`。 */
.spec {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* ★★ #291-③（2026-09-24 JACK）：「规格参数内容字体样式一致，从左向右排列，
       中间不要空行」—— 撤掉 #287② 的 `height:100% + align-content: space-between`
       （那是"3 行摊满整行高"的口径，本条推翻它）。改回**紧排**：
       行与行只隔 line-height，没有空行；内容不足 3 行时从上往下排，
       整格随 `.cl-row` 的 `align-items: center` 垂直居中。 */
    align-content: start;
    /* ★ `column-gap: 8px` —— 这是**照抄观感、不是照抄数字**的例外，写清楚免得下次又被"改回去"：
       老站槽宽 144px 里内容只占 ~80px ⇒ 天然有 64px 留白，所以它 `gap: 0` 也不会撞。
       新站列宽按比例缩放后（1440 档 173px / 1024 档 122px / **768 档 94px**），
       窄档留白归零 ⇒ 实测 768 屏幕出现 `VRWM (V):342V` 紧跟 `VBR(V)(Min):` 贴成一串
       （截图可见 `342VVBR(V)(Min):`）。补 8px 列间距是为了**复现老站那种"每格独立"的观感**，
       不是偏离老站。行间距现在交给上面的 space-between，不用 row-gap。 */
    column-gap: 8px;
    row-gap: 0;
    margin: 0;
}
/* #250-①：一项 = 一行「参数名:值」（照老站 Polarity:Uni 的写法）
   名弱值强，同行基线对齐；名字不再独占一行 ⇒ 9 项从 18 行压到 9 行
   ★ `flex-wrap: wrap`（窄档必需）：参数格是 40.6% 宽，768 档 3 列各约 94px，
     `VBR(V)(Min):380V` 整串 ≈110px 放不下。不 wrap 时 flex 会去缩值那一侧，
     配上 `overflow-wrap: anywhere` 就把 **`380V` 拆成 `380` + `V`**（实测截图可见）。
     wrap 之后值整体折到第二行、完整显示 —— 老站窄档也是这样（老站 80px 列里
     `VBR(V)(Min)` 占一行、`:6.4V` 折第二行，**值从不被拆**）。 */
.spec-i { min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0; }
/* ★★★ 2026-09-21 老站实测（这是"参数区和老站差很多"的**核心**）：
   老站 `DIV.za-spe` = `font-size:12.9px; line-height:20.64px; color:rgb(51,51,51); font-weight:400`
   —— **参数名和值在同一个元素里、同一个颜色 `#333`、同一个字号**，整片是**深色密排文字**。
   新站原来：名 `12px #999` 浅灰 + 值 `13px #333`，一深一浅一大小，还额外加了 2px 间隙。
   两个都在"层级化"，观感从"一整片规格数据"变成"一堆浅灰标签 + 深色数字"，这正是差异来源。
   ⇒ 照老站改：**名与值同为 13px、同为 `--hs-text`(#333)、间隙 0**（`:` 由 `.spec-k::after` 出，
     所以视觉上就是 `Polarity:Bi`，与老站的 `Polarity:Uni` 逐字符同构）。 */
/* ★ #312（2026-09-25 JACK 选 A）：行距 13px×1.84=23.92 → 24px ⇒ 格高恰 72.0（3×24）。
   13px 字号不变；.cl-meta（品类/封装行）不在此列，保持 1.84。 */
.spec-k { flex: 0 0 auto; font-size: 13px; color: var(--hs-text); line-height: 24px; }
.spec-k::after { content: ':'; }
.spec-v {
    margin: 0;
    min-width: 0;
    font-size: 13px; color: var(--hs-text); line-height: 24px;
    overflow-wrap: anywhere;
}
/* ★★ #291-③（2026-09-24 JACK）：「规格参数内容**字体样式一致**」——
   整列同值的浅灰弱化（#244=A / 悬案 #263）按本条**去掉**：全部参数一律
   13px `--hs-text`(#333)，不再有灰/黑之分（DOM 里的 `is-same` 类保留，
   只是不再有视觉差异 —— 想恢复时把下面这条颜色规则加回来即可）。
   实测 TVS 一页 16 条里约一半参数整列同值，灰黑夹杂正是"样式不一致"的来源。 */


/* ★★★ 四个动作按钮：**这是"和老站差很多"最扎眼的一处**（2026-09-21 JACK 第二次反馈后实测）
   老站：按钮 **120×30**、在 **240px 的格子里居中**（左右各 60px 白）、4 个竖排、**间距 10**、
        字号 **12px / line-height 18px** —— 观感是"一列小按钮"。
   新站原来：按钮**撑满整格 284px** 的通栏大色块（橙色的 Quick Enquiry 变成一条长横幅），
        间距 6、字号 13px —— 视觉重量比老站重一倍以上。
   ⇒ 照老站改：**定宽 + 居中 + 间距 10 + 12px 字**。
   宽度取 142px 的算法：老站按钮 120px ÷ 老站行宽 1080px = **11.1%**；
                        新站行宽 1278 × 11.1% ≈ **142px**（不是照搬 120，因为新站格子更宽）。
   高度：1 + 8 + 18 + 8 + 1 = **36px**（2026-09-24 JACK 要求调整；原 30 与老站同款）。 */
.cl-cell-act { display: flex; flex-direction: column; gap: 10px; }
/* ★★ 2026-09-24 第三次改（JACK 截图红框）：**撤掉**上一版"左右各 18px 内距"的收窄法 ——
   那版把按钮组居中在动作列里，右缘离列缘还有 18px，叠上列尾 3.09% 死空后右边空 119.5、
   左边只有 20，被他圈出来"左右留白差异很大"。
   ⇒ 改成**按钮组定宽 248、贴动作列右缘**（`margin-left:auto`）：
     · 间距缩至 5px，购物车保留原宽 76px，Datasheet / Enquiry 各增宽 5px；
     · 右缘 = 动作列右缘 = 行内容右缘 ⇒ 右留白 = 行内距 20 = **左留白 20**，对称；
     · `min(248px, 100%)`：窄档动作列不足 248 时自动封顶回 100%，三枚随格子缩，不溢出
       （1025 档动作列 228.9 ⇒ 三枚 69.6，实测无横向滚动）。
   ★ 上一版用 padding 收窄的理由（"不写死像素、随档位缩"）由 `min()` 接管 ——
     宽档定宽、窄档随格，两头都成立。 */
.cl-acts { display: flex; gap: 5px; width: min(248px, 100%); margin-left: auto; margin-right: 0; }
.cl-act {
    display: block; text-align: center;
    width: 142px; margin-left: auto; margin-right: auto;
    /* ★ 2026-09-24（JACK「按钮的高度也调整一下」）：竖向内距 5 → **8**，
       按钮高 30 → **36**（1+8+18+8+1）。宽度上一轮已经收窄到 76，
       30 高配上 76 宽显得又窄又扁；36 是站内次级按钮的常用高度，点击区也更大。
       表头 Enquiry list 同步 34 → 36（见 `.cl-list-head .qt-btn`）。 */
    padding: 8px 8px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    /* ★ 老站 `za-car` 实测文字色 `rgb(1,105,178)` = **#0169b2**，正是新站 `:root` 里的 `--hs-blue`。
       新站原来用 `--hs-text-2`(#555) 灰字 —— 四个按钮整体比老站"闷"一档。
       改成 `--hs-blue` 后是"蓝字白底细边"的次级按钮观感，与老站一致。 */
    font-size: 12px; color: var(--hs-blue); line-height: 18px;
    transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
/* 底色改成常态蓝字后，hover 不能再只是"变蓝"（会看不出变化）⇒ 用设计系统里的浅蓝底 */
.cl-act:hover { border-color: var(--hs-blue); background-color: var(--hs-blue-light); color: var(--hs-blue); }
/* 一屏只强调一件事 */
.cl-act-main {
    background-color: var(--hs-orange);
    border-color: var(--hs-orange);
    color: var(--hs-white); font-weight: 700;
}
.cl-act-main:hover {
    background-color: var(--hs-orange-dark);
    border-color: var(--hs-orange-dark);
    color: var(--hs-white);
}

/* 上排 Datasheet / Enquiry / 购物车，下排申请样品与上排总宽一致。
   上排总宽 248px：81 + 5 + 81 + 5 + 76。仅询价按钮使用橙色强调。
   761-1339px 沿用竖排；更窄的卡片恢复横排并按容器宽度计算按钮宽度。 */
/* 两个文字按钮均分购物车之外的宽度；min-width: 0 防止长文案撑破容器。
   ★ #288-⑤（2026-09-24 JACK）：三枚按钮文字加粗 700 —— 与 Enquiry 主按钮（本就 700）齐平，
     下排 Request sample 不在此容器内，维持常规字重。 */
.cl-acts > .cl-act {
    flex: 1 1 0; min-width: 0;
    width: auto; margin-left: 0; margin-right: 0;
    padding: 8px 6px;
    font-weight: 700;
}
/* 保留原 10px 间距时购物车的宽度，省出的 10px 由两个文字按钮各分 5px。 */
.cl-acts > .cl-act-cart { flex: 0 0 calc((100% - 20px) / 3); width: auto; }
/* 下排整宽。`.cl-act` 基类的 `width:142px` + auto 左右 margin 是给产品详情页
   那套竖排用的，不能在别处全局改掉 ⇒ 这里显式撤掉。
   ★ 2026-09-24：`width:100%` → `min(248px,100%)` + `margin-left:auto` ——
     下排仍 = 上排总宽（`#273`），且随上排一起**贴动作列右缘**。 */
.cl-cell-act > .cl-act-sample { width: min(248px, 100%); margin-left: auto; margin-right: 0; }
/* #291-③（2026-09-24 JACK）：「申请样品」按钮字体加粗 —— 与上排三枚（#288-⑤）同权重。 */
.cl-act-sample { font-weight: 700; }

/* ★ #272：购物车方钮内部 = `+` + 图标 + 角标，三个都要在同一行居中。
   原来是 `display:block` + 图标 `margin:0 auto`，现在改用 flex（图标自己不带 margin）。
   `justify-content: center` 让 `cl-cart-box` 在 88px（或 40px、或整宽）里居中。 */
.cl-acts > .cl-act-cart {
    display: flex; align-items: center; justify-content: center;
    position: relative;
}
/* ★★ #273：角标的定位锚从"按钮"改成"图标"。
   等宽之前按钮是 40px 定宽方钮，图标基本占满，角标挂按钮右上角 ≈ 挂图标右上角；
   等宽之后按钮 88px、图标仍在正中，角标若还挂按钮右上角就会飘到离图标 30px 的
   按钮边缘上 —— 读起来像"按钮的角标"而不是"购物车的角标"。
   加这层贴身盒子（宽度恒定 = `+`9 + 间隙1 + 图标18 = **28**，与按钮宽度无关）
   当锚，88 / 40 / 整宽三种形态下角标都贴在同一个位置。 */
.cl-cart-box {
    position: relative;
    display: flex; align-items: center; gap: 1px;
}
.cl-cart-plus {
    font-size: 13px; font-weight: 700; line-height: 1;
}
/* ★ 用 `visibility` 而不是 `display:none` 收起 `+`：
   两个状态（`+图标` / `图标+角标`）的**盒子宽度必须一样**，否则点一下
   图标会左右跳 9px；`visibility:hidden` 保留占位，图标不位移。
   代价是已加入时图标略偏左 4.5px —— `#273` 等宽后按钮 88px，
   图标本来就不在正中（被 `+` 顶偏），这 4.5px 更看不出来。 */
/* 已加入（JS 切 `.is-on`）：`+` 收起、角标出现、方钮变蓝底白图标。
   ★ 角标固定写「1」（模板里就是字面 1，不是 JS 填的）：本页每个型号只出现一次，
     这一格的数字只可能是 1 ⇒ 不需要 JS 刷文本，少一处状态同步。
   ★ 橙色沿用托盘角标 `.qt-n` 的同一个语汇（"计数"都用橙色），
     蓝底方钮上的橙点对比也够（#0169b2 上的 #ff9415）。 */
/* ★ 角标**尺寸与位置是量出来的，不是调出来的**（`analysis/_qt_geom.js` 实测）。
   尺寸仍是 12px —— 那是 `#272` 在 40px 方钮里量出来的结论（14px 会压掉篮子一块），
   换成 88px 后这一条不变，因为角标从来只跟图标打交道。
   位置（`#273`）：锚点换成 `.cl-cart-box`（宽 28）之后，
   `top:-4px; right:-5px` ⇒ 盒子右缘再往右出 5px、往上出 4px，
   角标占的是盒子的 18～30px、-4～8px —— 正压在 18px 图标的右上角上，
   向右探出到按钮的空白区（`cl-act-cart` 左右各有 30px 空，不会溢出按钮）。
   ★ 为什么不是 `top:0; right:0`：那样角标会整块坐进图标里（横向重叠 12px），
     把篮子压掉一半；要的是"挂在车角上的牌"，不是"贴在车身上的贴纸"。
   （第一版的 14/3 在 1x 屏上看着"就是个圆点"、在 2x 屏上才勉强能看，属于典型的
    "没量就调" —— 现在这条数字有探针兜着：`badgeInsideCard` 必须为真。） */
.cl-cart-n {
    position: absolute; top: -4px; right: -5px;
    display: none;
    min-width: 12px; height: 12px; padding: 0 2px;
    border-radius: 6px;
    background-color: var(--hs-orange); color: var(--hs-white);
    font-size: 9px; font-weight: 700; line-height: 12px; text-align: center;
}
.cl-act-cart.is-on {
    border-color: var(--hs-blue);
    background-color: var(--hs-blue);
    color: var(--hs-white);
}
.cl-act-cart.is-on .cl-cart-plus { visibility: hidden; }
.cl-act-cart.is-on .cl-cart-n { display: block; }

/* ★ 竖排降级：视口 < 1340 时动作列宽不足就不该硬挤
   （挤的结果是「Datasheet」被压成两行、把行高顶高，比降级更难看）。
   `#273` 后竖排是 4 行（上排三枚各占一行 + 下排样品一枚）：
   总高 = 30×4 + 10×3 = **150**，与 `#268`/`#272` 的竖排**完全相同** ⇒ 行高不变。 */
@media (max-width: 1339px) {
    .cl-acts { flex-wrap: wrap; }
    .cl-acts > .cl-act { flex: 1 1 100%; }
    .cl-acts > .cl-act-cart { flex: 1 1 100%; width: auto; }
}

/* ==========================================================================
   询价单入口（台账 `#264`~`#268` + `#272`，2026-09-21 JACK 拍板去掉账号方案）
   --------------------------------------------------------------------------
   命名空间 `qt-*`：与 cl-* / pd-* / hm-* 等平行，不互相套。

   ★★★ 2026-09-21 JACK `#272`：**入口从"左下角浮动"搬进了表头第 4 格**
     （原来贴着 `left:20px; bottom:20px` 常驻，只在勾了型号后才出现）。
     现在它**常显在 Action 列头的位置**，展开面板从按钮下方长出来。

   ★★ 为什么原来在左下角（这段历史留着，因为它决定了"还能挪去哪儿"）：
      右下 + 右缘 + 移动端整条底边**全被占** ——
        `main.css` `.sd`（right:4px，右缘竖条，宽 64）
        `main.css` `.sd-top`（right:4px, bottom:20px，右下角）
        `@media (max-width:1024px)` 把 `.sd` 变成 right:0/left:0/bottom:0 的**整条底边**
      ⇒ 桌面端右下/右缘/底下缘三条边都不可用。**这条约束依然成立**，
        所以 ≤760（表头整行 `display:none`）时的退路仍然是"左下角浮动"。

   ★ 两套形态，同一个元素：
       · 表头形态（`> 760px`）：`.qt` 是表头格里的 `position: relative` 容器，
         面板 `right:0; top:100%` 向下展开 → 见 `.cl-list-head .cl-cell-act-head`。
       · 浮动形态（`≤ 760px`，JS 加 `.qt-fixed` 并把容器挪到 body）：
         左下角浮动，面板向上展开。**为什么非挪不可**：≤760 时 `.cl-list-head`
         是 `display:none`，挂在里面的容器会跟着整块消失；CSS 没法把子元素
         "救"出来（`position:fixed` 也救不了 display:none 的祖先）。
         ⇒ 由 main.js §5 的 `place()` 换 parentNode，两套形态共用一份 DOM。

   ★ 通体直角（`--hs-radius`）与描边，不引入圆角胶囊 —— 与「全站直角」的
     设计系统语法一致；圆角只留给角标那一个数字（它没有别的形状可用）。
   ========================================================================== */
.qt { position: relative; }
.qt-fixed { position: fixed; left: 20px; bottom: 66px; z-index: 62; }

/* 两条 [hidden] 规则显式写出来，不指望浏览器默认样式表：
   站点 CSS 里若有会把 display 改回去的重置规则，托盘就会在"0 个型号"时
   照样出现 —— 那种"点了没反应"的空按钮是明确要避免的。
   ★ `#272` 起：`[hidden]` 只对**浮动形态**生效（0 个型号时整块不出现）；
     表头形态下它就是列头，**0 个型号也必须常显**（否则整列没有头，
     也少了"这里怎么用"的入口）。判断在 JS 的 paintCount() 里。 */
.qt[hidden] { display: none; }
.qt-n[hidden] { display: none; }
.qt-panel[hidden] { display: none; }

/* 按钮：两套配色 —— 表头里是"蓝底上的白底蓝字按钮"，浮在页面上是"白底上的蓝底白字按钮"。
   不写成一套的原因很直白：白底按钮放在白页面上会看不见边框以外的存在感，
   蓝底按钮放在蓝表头上会糊成一团。 */
.qt-btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 0 16px;
    border: 1px solid var(--hs-blue);
    border-radius: var(--hs-radius);
    background-color: var(--hs-blue); color: var(--hs-white);
    font-size: 14px; font-weight: 700; line-height: 1;
    white-space: nowrap;
    cursor: pointer;
}
.qt-btn:hover { background-color: var(--hs-blue); border-color: var(--hs-blue); }
.qt-btn-ico { display: block; width: 20px; height: 20px; }
.qt-n {
    min-width: 20px; height: 20px; padding: 0 5px;
    border-radius: 10px;
    background-color: var(--hs-orange); color: var(--hs-white);
    font-size: 12px; font-weight: 700; line-height: 20px; text-align: center;
}
/* 下拉箭头：`is-open` 时翻 180°。★ 它挂在 `.qt` 的 `is-open` 上，
   不写 `.qt-btn` 上 —— 状态本来就属于"这个组件开没开"，不属于某个按钮。
   #299（2026-09-25 JACK）：20px + 描边 2.4（AdIcon 默认 1.7），「箭头加粗大一点」。 */
.qt-caret-ico {
    display: block; width: 20px; height: 20px;
    transition: transform .18s ease;
}
.qt-caret-ico path { stroke-width: 2.4; }
.qt.is-open .qt-caret-ico { transform: rotate(180deg); }

/* 表头形态：白底蓝字，高度压到 34（表头行高 10+34+10 = 54，
   比原来的 38 高 16px —— 换来一个常显的入口按钮，值）。
   `#276 = 乙`：`width: 100%` 让它拉满整格（1440 档 283.7px），
   左右缘与下面 48 行的动作块对齐。
   ★ `justify-content: center` 是**有意的**：`.qt-btn` 基类是 `inline-flex` 默认贴左，
     拉满之后若贴左，文字会顶到格子左缘，而左边三个列名都是居中的（`#274 = 甲`）——
     整条表头就这一处贴左会很跳。⇒ 内容整组居中于 283.7 的长条。
   ★ #288-③（2026-09-24 JACK 明确指示）：按钮内部顺序改为
     `文字 → 数字角标 → 购物车图标 → 三角箭头` —— 购物车图标从文字左侧
     挪到「文字与下拉箭头之间」，图标 18→20、箭头 14→16（各放大 11%/14%）。 */
.cl-list-head .qt-btn {
    width: 100%; height: 36px; padding: 0 12px;
    justify-content: center;
    border-color: var(--hs-white);
    background-color: var(--hs-white); color: var(--hs-blue);
    font-size: 13px;
}
.cl-list-head .qt-btn:hover { background-color: var(--hs-blue-light); border-color: var(--hs-blue-light); }
.cl-list-head .qt-n { min-width: 18px; height: 18px; font-size: 11px; line-height: 18px; }
/* 浮动形态（≤760）：恢复原来的 48px 触控高度 + 蓝底白字 */
.qt-fixed .qt-btn { height: 48px; font-size: 14px; }
.qt-fixed .qt-btn-ico { width: 22px; height: 22px; }
.qt-fixed .qt-caret-ico { display: none; }   /* 浮动形态向上展开，箭头朝下没意义 */

/* 展开的清单。表头形态：锚在按钮右边（`right:0`）向下展开 ——
   锚右边而不是左边，是因为按钮本身离版心右缘只有 82px，
   300px 的面板从左边锚出去会冲出视口。向下展开不会遮住按钮本身。 */
.qt-panel {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 64;
    /* 窄屏时 300 会顶到屏幕右边（390 视口 − 左右各 20 = 350 可用），
       所以宽度用 min() 夹一下，不写死。 */
    width: min(320px, calc(100vw - 40px));
    max-height: 60vh; overflow: auto;
    border: 1px solid var(--hs-line-3);
    border-top: 3px solid var(--hs-blue);      /* 与首页/列表卡片同一条语法 */
    background-color: var(--hs-white);
    /* ★ 表头是 `font-weight:700; color:#fff`，面板若不自报家门会把这两条继承下去
       （型号名变粗、灰字变白 = 字看不见）。这里一次性断开继承。 */
    font-weight: 400; color: var(--hs-text);
}
/* 浮动形态：改回向上展开（与 `#264` 定稿一致） */
.qt-fixed .qt-panel { top: auto; bottom: 58px; left: 0; right: auto; }
.qt-head {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--hs-line);
    font-size: 14px; font-weight: 700; color: var(--hs-text);
}
.qt-head-n { font-size: 12px; color: var(--hs-text-3); font-weight: 400; }
.qt-list { margin: 0; padding: 0; list-style: none; }
.qt-item {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--hs-line);
}
.qt-item-name {
    flex: 1 1 auto; min-width: 0;
    font-size: 14px; color: var(--hs-text); line-height: 1.4;
    overflow-wrap: anywhere;      /* 长型号（>20 字符）不许把面板撑破 */
}
.qt-item-name a { color: var(--hs-text); }
.qt-item-name a:hover { color: var(--hs-blue); }
.qt-item-pkg { flex: 0 0 auto; font-size: 12px; color: var(--hs-text-mute); }
.qt-x {
    flex: 0 0 auto; width: 24px; height: 24px; padding: 0;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; line-height: 1; color: var(--hs-text-3);
    cursor: pointer;
}
.qt-x:hover { border-color: var(--hs-blue); color: var(--hs-blue); }
.qt-empty { padding: 20px 14px; margin: 0; font-size: 13px; color: var(--hs-text-3); text-align: center; }
.qt-foot { display: flex; gap: 8px; padding: 12px 14px; }
.qt-clear {
    flex: 0 0 auto; padding: 10px 14px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; color: var(--hs-text-2);
    cursor: pointer;
}
.qt-clear:hover { border-color: var(--hs-blue); color: var(--hs-blue); }
/* 整个托盘只有这一个橙色块（一屏只强调一件事 ⇒ 只有一个「提交」） */
.qt-go {
    flex: 1 1 auto; padding: 10px 14px;
    border: 1px solid var(--hs-orange);
    background-color: var(--hs-orange); color: var(--hs-white);
    font-size: 14px; font-weight: 700;
    cursor: pointer;
}
.qt-go:hover { background-color: var(--hs-orange-dark); border-color: var(--hs-orange-dark); }

/* 飞射提示：点购物车按钮时，一个小方块从按钮位置飞向托盘。
   `position: fixed` + `transform` 过渡 —— 只动 transform，不触发布局重排。
   `prefers-reduced-motion` 下 JS 直接跳过整个动画（只更新角标数字）。 */
.qt-fly {
    position: fixed; z-index: 80;
    width: 28px; height: 28px;
    border: 1px solid var(--hs-blue);
    background-color: var(--hs-blue); color: var(--hs-white);
    font-size: 12px; font-weight: 700; line-height: 26px; text-align: center;
    pointer-events: none;
    transition: transform .55s cubic-bezier(.4, .1, .6, 1), opacity .4s ease .15s;
}
.qt-fly.is-out { opacity: 0; }

/* ★ #272：原来这里有一条 `@media (max-width:1024px) { .qt { bottom: 66px } }`
   （把左下角浮动托盘抬到底边工具条之上）。入口搬进表头后，`.qt` 在 >760
   是 `position:relative`，再写 `bottom` 就变成了一个无意义的偏移量；
   浮动形态的"抬高"已经写在 `.qt-fixed` 的 `bottom:66px` 里 ⇒ 这条删除。 */

/* 分组容器页的器件类型入口卡：这一类页的客户第一问是"我要哪一类器件"，
   先回答它，再往下看型号。 */
/* #290-③：原「按器件类型查看」.cl-entries 系列规则已随模板删除（样式上移为 .cl-subtab*）。 */

/* 空态：给出路，不只说一句"没有结果" —— 干说一句等于让客户走进死胡同。
   两条出路：清掉自己加的严格条件、或退回产品中心重新选品类。 */
.cl-empty { padding: 60px 40px; text-align: center; }
.cl-empty-msg { margin: 0 0 18px; font-size: 16px; color: var(--hs-text-3); line-height: 1.7; }
.cl-empty-act { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 0; }
.cl-empty-btn {
    padding: 10px 22px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; color: var(--hs-text-2);
}
.cl-empty-btn:hover { border-color: var(--hs-blue); color: var(--hs-blue); }

/* 分页 + 跳页：44 页时一页页翻太慢。
   跳页是独立 GET 表单并带住当前筛选与排序，否则一跳就把条件丢掉。
   2026-09-25 JACK：跳页表单移进 .cl-pager 内**并排一行**（原先独占第二行）；
   表单自身是 flex 项，.cl-pager 装不下时窄屏仍自然换行。 */
.cl-pager { padding-bottom: 18px; }
.cl-jump {
    display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-left: 16px;
    font-size: 14px; color: var(--hs-text-3);
}
.cl-jump-label { display: inline-flex; align-items: center; gap: 6px; }
.cl-jump-input {
    width: 64px; padding: 6px 8px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; color: var(--hs-text); text-align: center;
}
.cl-jump-go {
    padding: 7px 16px;
    border: 1px solid var(--hs-line-3);
    background-color: var(--hs-white);
    font-size: 14px; color: var(--hs-text-2);
    cursor: pointer;
}
.cl-jump-go:hover { border-color: var(--hs-blue); color: var(--hs-blue); }


/* ==========================================================================
   品类页 · 窄屏（≤760px）：行式表格退成卡片
   --------------------------------------------------------------------------
   台账 #236=A。桌面那套 4 列网格在 390px 下每列只剩 40~60px，参数名会折成
   一字一行（这个坑我上一轮在效果图的标注表上踩过一次）。
   退成卡片后每张卡内部仍然是 2 列参数网格，比横向挤压可读得多。
   ★ 与首页卡片同一条语法：1px 细边 + 3px 蓝顶边。
   ★ 不换 DOM，只换排布 —— 爬虫与无 JS 拿到的 HTML 与桌面完全一致。
   ========================================================================== */
@media (max-width: 760px) {
    .cl-filter { padding: 14px 16px 12px; }
    /* 窄屏：父容器已 nowrap+横向滚（#295），每框固定占满一整行宽
       （flex-basis 100% + 不许 shrink ⇒ 一屏一个维度，左右滑着看）。 */
    .cl-facet { flex: 0 0 100%; }
    .cl-filter-foot { flex-wrap: wrap; }
    .cl-filter-apply { flex: 1 1 auto; }

    .cl-list-head { display: none; }
    .cl-list { background-color: transparent; }

    /* 卡片：图 + 型号一行，参数一行，动作一行 */
    .cl-row {
        display: grid;
        grid-template-columns: 104px minmax(0, 1fr);   /* 跟着桌面档的图宽（104）走 */
        gap: 10px 12px;
        margin-bottom: 12px;
        padding: 14px;
        border: 1px solid var(--hs-line);
        border-top: 3px solid var(--hs-blue);
        background-color: var(--hs-white);
    }
    .cl-row:hover { background-color: var(--hs-white); }
    .cl-cell-pic  { grid-column: 1; grid-row: 1; }
    .cl-cell-name { grid-column: 2; grid-row: 1; }
    .cl-cell-spec { grid-column: 1 / -1; grid-row: 2; align-self: start; }
    .cl-cell-act  { grid-column: 1 / -1; grid-row: 3; }
    .cl-pic { width: 72px; height: 72px; }

    /* 窄档撤掉桌面态的"参数摊满整行"（桌面 `.cl-cell-spec` stretch + `.spec` space-between）：
       窄卡里参数本来就折成 2 列多行，再摊高会把卡片撑出一截空白。 */
    .spec { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px; height: auto; align-content: start; }

    .cl-cell-act { flex-direction: row; flex-wrap: wrap; padding: 0; }
    /* ★ 桌面档给 `.cl-act` 加了 `width: 142px` + auto 左右 margin（照老站的定宽居中）。
       窄屏是 flex 横排，**必须把这两个撤掉**，否则第一个按钮被 `margin-left: auto`
       推到中间、后续按钮排不到右边。 */
    .cl-act { width: auto; margin-left: 0; margin-right: 0; flex: 1 1 calc(50% - 5px); }
    /* ★ `#273`：样品按钮在下排、**整宽**，所以必须显式压过上面那条 `50% - 5px`。 */
    .cl-cell-act > .cl-act-sample { flex: 1 1 100%; }
    /* 窄屏恢复上排三个按钮横排，同样把缩小间距省出的宽度分给文字按钮。 */
    .cl-cell-act > .cl-acts { flex: 1 1 100%; flex-wrap: wrap; }
    .cl-acts > .cl-act { flex: 1 1 0; min-width: 0; width: auto; padding: 5px 6px; }
    .cl-acts > .cl-act-cart { flex: 0 0 calc((100% - 20px) / 3); width: auto; }

    .cl-tabs-sep { display: none; }   /* #316：窄屏折行，「|」不再有意义，隐藏 */
    .cl-jump { margin-left: 0; }   /* 换行后跳页独占一行，不再缩进 */
}


/* ==========================================================================
   内容栏目页 / 文章详情页
   --------------------------------------------------------------------------
   老站的内容页（Applications / news / TechForum …）是套模板渲出来的，
   版式与产品页雷同、正文没有标题层级。这里做成「宽正文 + 轻卡片」的阅读版式，
   原因有两个：
     · 应用方案类长文（本站最长 66K 字符）需要舒服的行宽，否则读者跳走，
       停留时长是 Google 评估内容质量的实际信号之一；
     · 卡片列表带摘要 + 日期 + 阅读时长，让读者（和爬虫）一眼看清这一页有什么。
   ========================================================================== */
.ct { max-width: var(--hs-container); margin: 0 auto; padding: 0 0 90px; }

.ct-head { background-color: var(--hs-white); padding: 40px 40px 30px; }
/* §144：栏目页 ct-kicker（type_label "Resources"/资讯与支持）已随模板删除，
   类保留给 /search 的「站内搜索/Search」小标使用 */
.ct-kicker { font-size: 14px; color: var(--hs-blue); margin: 0 0 10px; letter-spacing: .04em; text-transform: uppercase; }
.ct-kicker a { color: var(--hs-blue); text-decoration: underline; }
.ct-title { font-size: 30px; line-height: 1.35; color: var(--hs-text); margin-bottom: 12px; word-break: break-word; }
/* §144：导语 17→14，与全站正文字号统一（§140 口径：正文 14） */
.ct-lede { font-size: 14px; line-height: 1.8; color: var(--hs-text-2); max-width: 1000px; margin: 0 0 12px; }
.ct-count { font-size: 14px; color: var(--hs-text-3); margin: 0; }
.ct-fallback {
    margin: 14px 0 0; padding: 8px 14px;
    background-color: #fff8e6; border-left: 3px solid var(--hs-orange);
    font-size: 14px; color: #8a6100;
}

/* 子栏目入口 */
.ct-subs { display: flex; flex-wrap: wrap; gap: 10px; background-color: var(--hs-white); padding: 0 40px 30px; }
.ct-sub {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 18px;
    border: 1px solid var(--hs-line-3);
    border-radius: var(--hs-radius);
    font-size: 15px; color: var(--hs-text-2);
    background-color: var(--hs-white);
}
.ct-sub:hover { border-color: var(--hs-blue); color: var(--hs-blue); background-color: var(--hs-blue-light); }
.ct-sub-count { font-size: 12px; color: var(--hs-text-mute); background: var(--hs-bg); padding: 0 7px; border-radius: 10px; }

/* 栏目正文 */
.ct-body { background-color: var(--hs-white); padding: 10px 40px 30px; }
/* §144：区块大标题 22→28，与 .sv-h2 / .ab-sec-h 统一（§十二：区块大标题 28px） */
.ct-h2 { font-size: 28px; color: var(--hs-text); margin: 0 0 20px; }

/* 富文本正文容器：既用于栏目正文，也用于文章正文 */
.ct-richtext { font-size: 16px; line-height: 1.9; color: var(--hs-text-2); word-break: break-word; }
.ct-richtext > :first-child { margin-top: 0; }
.ct-richtext h2, .ct-richtext h3, .ct-richtext h4 {
    color: var(--hs-text);
    margin: 32px 0 12px;
    line-height: 1.45;
}
.ct-richtext h2 { font-size: 22px; }
.ct-richtext h3 { font-size: 19px; }
.ct-richtext h4 { font-size: 17px; }
/* §144：DB 富文本里的 ab-* 结构化标题（公司简介等）不许被上面的元素选择器
   (0,1,1) 压掉 —— 用 (0,2,0) 抬回来，保持与母页同字号（28/16） */
.ct-richtext .ab-sec-h { font-size: 28px; }
.ct-richtext .ab-h3,
.ct-richtext .ab-card-h,
.ct-richtext .ab-app-h { font-size: 16px; }
.ct-richtext ul, .ct-richtext ol { margin: 0 0 18px; padding-left: 22px; }
.ct-richtext ul { list-style: disc; }
.ct-richtext ol { list-style: decimal; }
.ct-richtext li { margin-bottom: 8px; }
.ct-richtext img, .ct-richtext table, .ct-richtext iframe { max-width: 100%; height: auto; }
.ct-richtext table { border-collapse: collapse; margin-bottom: 20px; }
.ct-richtext table td, .ct-richtext table th { border: 1px solid var(--hs-line); padding: 8px 12px; }
.ct-richtext blockquote {
    margin: 20px 0; padding: 12px 20px;
    border-left: 3px solid var(--hs-blue);
    background-color: var(--hs-bg);
    color: var(--hs-text-2);
}
.ct-richtext a { color: var(--hs-blue); text-decoration: underline; }
/* 老站富文本里带内联 font-size / line-height，统一压平，避免几代编辑器样式打架 */
.ct-richtext [style*="font-size"] { font-size: inherit !important; }
.ct-richtext p { margin: 0 0 1.1em; }

/* 文章列表 */
.ct-list-wrap { background-color: var(--hs-white); padding: 34px 40px 10px; }
.ct-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.ct-card { border: 1px solid var(--hs-line); transition: border-color .2s ease, box-shadow .2s ease; }
.ct-card:hover { border-color: var(--hs-blue); box-shadow: 0 3px 14px rgba(1, 105, 178, .12); }
.ct-card-link { display: flex; flex-direction: column; height: 100%; }
.ct-card-media { display: block; aspect-ratio: 16 / 10; overflow: hidden; background-color: var(--hs-bg); }
.ct-card-media img { width: 100%; height: 100%; object-fit: cover; }
.ct-card-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 18px 20px 20px; }
.ct-card-title {
    display: block; font-size: 17px; font-weight: 700; line-height: 1.5; color: var(--hs-text);
    margin-bottom: 10px; word-break: break-word;
}
.ct-card:hover .ct-card-title { color: var(--hs-blue); }
.ct-card-intro {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 14px; line-height: 1.75; color: var(--hs-text-3);
    margin-bottom: 14px;
}
.ct-card-meta { display: block; margin-top: auto; font-size: 13px; color: var(--hs-text-mute); }

/* news 行式列表（2026-09-29 台账 §147，仅 news 家族）：左图 + 右内容，每页 10 条 */
.ct-newslist { background-color: var(--hs-white); padding: 6px 40px; }
.ct-news { list-style: none; margin: 0; padding: 0; }
.ct-news-row { border-bottom: 2px solid var(--hs-line); }
.ct-news-row:last-child { border-bottom: 0; }
.ct-news-link { display: flex; gap: 24px; align-items: flex-start; padding: 20px 0; text-decoration: none; }
.ct-news-media { flex: 0 0 240px; aspect-ratio: 16 / 10; overflow: hidden; background-color: var(--hs-bg); }
.ct-news-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ct-news-body { flex: 1 1 auto; min-width: 0; }
.ct-news-title {
    display: block; font-size: 17px; font-weight: 700; line-height: 1.5;
    color: var(--hs-text); word-break: break-word;
}
.ct-news-link:hover .ct-news-title { color: var(--hs-blue); }
.ct-news-intro {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 8px; font-size: 14px; line-height: 1.75; color: var(--hs-text-3);
}
.ct-news-meta { display: block; margin-top: 10px; font-size: 13px; color: var(--hs-text-mute); }

/* 招聘职位卡片（仅 carrers 栏目用，参考老站 /about/recruit 的信息层次） */
.jb-list { display: flex; flex-direction: column; gap: 14px; }
.jb-card { border: 1px solid var(--hs-line); transition: border-color .2s ease, box-shadow .2s ease; }
.jb-card:hover { border-color: var(--hs-blue); box-shadow: 0 3px 14px rgba(1, 105, 178, .12); }
.jb-card-link { display: flex; align-items: flex-start; gap: 24px; padding: 22px 26px; }
.jb-card-main { flex: 1 1 auto; min-width: 0; }
.jb-card-title { display: block; font-size: 18px; font-weight: 700; line-height: 1.5; color: var(--hs-text); margin-bottom: 8px; word-break: break-word; }
.jb-card:hover .jb-card-title { color: var(--hs-blue); }
.jb-card-intro { display: block; font-size: 14px; line-height: 1.75; color: var(--hs-text-3); }
.jb-card-side { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.jb-tag { font-size: 13px; color: var(--hs-text-3); background-color: var(--hs-bg); padding: 4px 12px; white-space: nowrap; }
.jb-go { font-size: 13px; font-weight: 600; color: var(--hs-blue); white-space: nowrap; }
.jb-count { display: inline-block; margin-left: 10px; font-size: 14px; font-weight: 400; color: var(--hs-text-mute); }

.ct-pager { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; background-color: var(--hs-white); padding: 30px 40px 40px; }
.ct-empty { background-color: var(--hs-white); padding: 60px 40px; text-align: center; color: var(--hs-text-3); }

/* 行动召唤条 */
.ct-cta {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 18px;
    margin-top: 24px; padding: 26px 40px;
    background-color: var(--hs-blue-light);
    border-left: 4px solid var(--hs-blue);
}
.ct-cta-text { display: flex; flex-direction: column; gap: 4px; }
.ct-cta-text strong { font-size: 17px; color: var(--hs-text); }
.ct-cta-text span { font-size: 15px; color: var(--hs-text-2); }
.ct-cta .pd-btn { margin: 0; flex: 0 0 auto; }
.ct-cta-inline { margin: 40px 0 0; }

/* ---- 文章详情 ---- */
/* §148（2026-09-29 JACK「详情页优化宽度、排版」）：
   1) 列宽 980 → 1250（JACK 拍板「文章宽度调整到 1250」；中间稿 880 已被覆盖）：
      正文行宽 = 1250 − 80 = 1170px；
   2) 边缘统一：§140 白名单在 1025~1618 档把 .ct-head/.ct-cover/.ct-related 抬到 68，
      而本页 .ct-richtext/.ct-lead/.ct-cta 是 40 ⇒ 实测文字左缘出现 270/290/298 三种值
      （正文比标题凸出 28px）。详情页是居中窄列，右缘对齐 .sd 的口径不适用，
      在本作用域统一压回 40 —— 六块内容盒左缘全部 = 列左缘 + 40。
      只写 .ct-detail 前缀 (0,2,0)，压过白名单 (0,1,0)；列表页 / 栏目页不受影响。 */
.ct-detail { max-width: 1250px; }
.ct-detail .ct-head,
.ct-detail .ct-cover,
.ct-detail .ct-related { padding-left: 40px; padding-right: 40px; }
/* §148 补：CTA 条背景从列边 95 顶到头，与导语框（缩进 40 起）两种框宽打架
   ⇒ 同步缩进 40，全部可视框统一落在「列左缘 + 40」一条网格线上 */
.ct-detail .ct-cta { margin-left: 40px; margin-right: 40px; }
/* §148-b（2026-09-29 JACK「文章内图片大小固定一下，高度减少 30%」）：
   1) 封面：统一裁到模板声明的 1000×420（2.38:1）+ object-fit: cover 不变形。
      1250 列下 1536×944 原图实高 719px → 491px，约 −32%；
   2) 正文图：max-height 500px 封顶、等比缩不裁切（正文图多为新闻照片/图表，
      裁切会丢信息）；小于 500px 的图不受影响。 */
.ct-detail .ct-cover img { aspect-ratio: 1000 / 420; object-fit: cover; }
.ct-detail .ct-richtext img { max-height: 500px; }
.ct-article { background-color: var(--hs-white); padding-bottom: 40px; }
.ct-cover { margin: 0; padding: 0 40px 10px; }
.ct-cover img { display: block; width: 100%; height: auto; }
/* lead 段（导语）：比正文略大一点，区别于普通段落 */
.ct-lead {
    margin: 0 40px 24px;
    padding: 16px 20px;
    background-color: var(--hs-bg);
    border-left: 3px solid var(--hs-orange);
    font-size: 14px; line-height: 1.8; color: var(--hs-text-2); /* §144：17→14 与全站正文统一 */
}
.ct-detail .ct-richtext { padding: 0 40px; }

.ct-related { margin-top: 24px; background-color: var(--hs-white); padding: 34px 40px; }
.ct-related-list li { border-bottom: 1px solid var(--hs-line-2); }
.ct-related-list li:last-child { border-bottom: 0; }
.ct-related-list a {
    display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
    padding: 14px 0; font-size: 16px; color: var(--hs-text);
}
.ct-related-list a:hover { color: var(--hs-blue); padding-left: 4px; }
.ct-related-title { word-break: break-word; }
.ct-related-date { flex: 0 0 auto; font-size: 13px; color: var(--hs-text-mute); }

/* ==========================================================================
   首页
   ========================================================================== */
/* ★★ 2026-09-19 JACK 指令：hero 左右通栏（到边 100%）。
   难点不是「拉满宽」，而是**拉满之后文字仍要和下方区块对齐**。
   hero 是 .hm 的子元素，被 .hm 的左右内边距夹住；直接给 hero 加负外边距
   会把它推到视口边缘，但它自己的左右内边距还停在 40px —— 于是 hero 里的
   H1 会比下面区块的标题**偏左 30px**，通栏就成了对齐事故。

   解法：把「页面留白」和「区块内边距」拆成两个变量 ——
     --hm-gutter = 页面留白（.hm 的左右 padding：30 / 20）
     --hm-pad    = 区块内边距（.hm-sec / .hm-cats 的左右：40 / 32 / 20 / 14）
   通栏元素 = 负外边距 -gutter + 左右内边距 (gutter + pad)。
   两者相抵后，内容起点 = gutter + pad，与 .hm-sec > .hm-inner 的左边缘完全相等。

   ⚠ 这两个变量必须**成对维护**：任何一档 @media 改了 gutter 或 pad，
     通栏 hero 的负外边距与内边距会自动跟随，不会再错位。
   ⚠ 不要再在别处单独给 .hm 写 padding-left/right 覆盖 ——
     那会让 -gutter 与真实内边距对不上，撑出横向滚动条（见 ≤768 断点处的说明）。 */
/* ★★★ 2026-09-20（JACK：「感觉首页整体背景是一块一块拼装成的，而且背景的宽度
   不一致，优化一下背景的整体感」）—— **首页主区改成一整片白底**。

   改前的实际观感（`analysis/_home_bg_probe.js` 实测，1440 / clientWidth 1425）：
     每个区块都是「白底块 + 30px 下外边距」，而块与块之间露出的是 body 的
     `--hs-bg`（#f4f7fb）。于是整页变成**七八张白纸贴在灰板上**：
       · 缝的节奏还不一致：`.hm-cats` 与 `.hm-mid` 的 margin-bottom 分别是 0 和 30，
         只有 `.hm-sec` 是 30 ⇒ 实测缝宽序列是 0 / 0 / 30 / 30 / 30 / 30 / 30；
       · `#fff` 与 `#f4f7fb` 的亮度只差 3%，那 30px 根本读不出"有意留的分隔"，
         只读得出"两块白板没对齐" ⇒ 这就是"拼装感"的来源。

   解法不是把灰加深（那会把"卡片浮在灰底"的整站设计语言一起改掉），
   而是**让灰缝消失**：`.hm` 自己铺白底 ⇒ 所有区块的白底、所有 30px 灰缝
   全部落进同一片白色里，页面从"拼装"变成"一张纸"。
   ⇒ 背景只剩两种宽度：hero（通栏出血）与主区（视口 − 60），且两者同色系无接缝。

   ⚠ 为什么只加这一条、**不动** `.hm-cats` / `.hm-sec` 的 margin：
     它们的 30px 下外边距现在落到白底上、变成**白留白**，正好是区块之间的呼吸位
     （实测每两块之间 = 48 + 30 + 48 = 126px）。留着它，将来若判定"还是要有灰缝"，
     删掉本行即完全复原旧观感 —— 一行可回滚。
   ⚠ `.hm-ai` 的注释写着「不含任何背景色」—— 本行之后它**等效于白底**，
     正是那句话想要的效果（不给自己单独的颜色），不必再去改它。
   ⚠ 白底会不会让白盒子消失：不会。`.ai-bar` 有 `--hs-line-3` 边框 + 阴影、
     `.hm-card` / `.sd-link` 有 `--hs-line` 边框、`.hm-dl-card` / `.hm-post-media`
     用的是 `--hs-bg` 灰底 —— 五种盒子在白底上都仍有边界（实测出图核对过）。 */
.hm { --hm-gutter: 30px; --hm-pad: 40px; background-color: var(--hs-white); padding: 0 var(--hm-gutter) 90px; }
.hm-inner { max-width: var(--hs-container); margin: 0 auto; }
.hm-hero {
    background-color: var(--hs-white);
    margin: 0 calc(-1 * var(--hm-gutter)) 30px;
    padding: 70px calc(var(--hm-pad) + var(--hm-gutter)) 60px;
}
.hm-title { font-size: 38px; line-height: 1.3; color: var(--hs-blue); margin-bottom: 18px; }
.hm-lede { font-size: 18px; line-height: 1.8; color: var(--hs-text-2); max-width: 900px; margin-bottom: 14px; }
.hm-stat { font-size: 15px; color: var(--hs-text-3); margin: 0; }
.hm-cats { background-color: var(--hs-white); padding: var(--hs-sp-7) var(--hm-pad); }
/* ★ 2026-09-19：24 → 28px。标题原来是「12px 英文小标签 + 24px 标题」两层，
   JACK 定「保留一份」——去掉小标签后，标题要独自承担区块的视觉入口，
   28px 才压得住下面 19px 的卡片名。行高 1.6（=38.4px）是继承来的，对标题太松，
   收到 1.3；不加负字距——这条规则中英共用，中文用负字距会粘连。 */
.hm-h2 { font-size: 28px; line-height: 1.3; color: var(--hs-text); margin-bottom: var(--hs-sp-5); }
/* #374 自适应卡片栅格（JACK 2026-09-27）：grid 改 flex wrap，宽度类 .wK 由控制器算。
   规则：<4 块一行；偶数两行等分；奇数上少下多（5→2+3、7→3+4）。
   卡高等高：flex 同一行的 item 默认 stretch，与原 grid 行为一致。
   --gw = 本容器的 gap，宽度公式按「K 卡铺满一行含间隙」反推。 */
.hm-grid { display: flex; flex-wrap: wrap; align-items: stretch; --gw: 20px; gap: var(--gw); }
.hm-adapt > .w1 { width: 100%; }
.hm-adapt > .w2 { width: calc((100% - var(--gw)) / 2); }
.hm-adapt > .w3 { width: calc((100% - 2 * var(--gw)) / 3); }
.hm-adapt > .w4 { width: calc((100% - 3 * var(--gw)) / 4); }
.hm-adapt > .w5 { width: calc((100% - 4 * var(--gw)) / 5); }
.hm-adapt > .w6 { width: calc((100% - 5 * var(--gw)) / 6); }
.hm-adapt > .w7 { width: calc((100% - 6 * var(--gw)) / 7); }
/* ★ position:relative 是给 .hm-card-name::after 的**伸展层**当定位基准（见下）。 */
.hm-card { position: relative; border: 1px solid var(--hs-line); border-top: 3px solid var(--hs-blue); transition: box-shadow .2s ease; }
.hm-card:hover { box-shadow: 0 4px 16px rgba(1, 105, 178, .14); }
/* ★ 2026-09-19 JACK 指令：计数字样移到**右下角** + `>>`，读作「了解更多详情」。
   实现要点：
     · .hm-card-link 改成 flex 纵向 —— 否则 margin-top:auto 不生效，计数压不到底部；
     · .hm-card-count 用 align-self + margin-top:auto 靠右下。
   ★★ #154 加了「二级子类链接」之后，卡**不能**再用「一个 <a> 包整卡」——
     <a> 里套 <a> 是非法 HTML，浏览器会自动闭合外层 <a>、把 DOM 拆坏。
     改用标准「伸展链接（stretched link）」：
       · 外层改 <div>；标题是唯一的 URL 链接；
       · .hm-card-name::after 铺满整张卡 ⇒ **整卡依然可点**；
       · .hm-card-subs 提到 z-index:1 ⇒ 子类各自可点，不被伸展层吃掉。
   ⚠ 卡片高度由网格行决定（同行卡片等高）⇒ 内容少的卡会有中间留白。
     TVS Diodes / Bridge Rectifiers **本来就没有子类**（型号直接挂在一级类上），
     所以这两张卡不会有子类列表 —— 是同口径过滤的正确结果，不是漏渲染。 */
.hm-card-link { display: flex; flex-direction: column; height: 100%; padding: 24px 22px; }
.hm-card-name { display: block; font-size: 19px; font-weight: 700; color: var(--hs-text); margin-bottom: 8px; }
.hm-card-name::after { content: ''; position: absolute; inset: 0; }
.hm-card:hover .hm-card-name { color: var(--hs-blue); }
/* 卡内二级子类（#154 B）：**标签式换行列表**，不是竖排 ——
   竖排 7 项会把卡片从 114px 拉到 ~270px，8 张卡两行就多出 300+px 页面高度。
   ★ 每个子类都是**真链接、anchor text 就是子类名**，这才是本卡 SEO 价值的主体，
     所以必须是 <a> 而不是纯文字（这也是上面必须换掉「a 包整卡」的原因）。
   ★ 视觉对齐站内既有标签语言 `.tf-tag-prod`（技术社区的产品标签）：
     浅灰底 + 圆角 + 蓝底白字 hover。原来写成「灰色裸文字」时，
     7 个子类会连排成一段像正文，既不好扫读、也看不出可以点。 */
.hm-card-subs {
    position: relative; z-index: 1;      /* 盖在伸展层之上，保证可点 */
    display: flex; flex-wrap: wrap; gap: var(--hs-sp-1) var(--hs-sp-2);
    margin-top: var(--hs-sp-3);
}
.hm-card-subs a {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--hs-radius);
    background-color: #f0f0f0;
    font-size: 13px; line-height: 1.6;
    color: var(--hs-text-3);
}
.hm-card-subs a:hover { background-color: var(--hs-blue); color: var(--hs-white); }
.hm-card-count {
    display: inline-block; align-self: flex-end;      /* 右下角 */
    margin-top: auto;                                 /* 压到卡片底部 */
    font-size: 13px; font-weight: 600;
    color: var(--hs-blue);
    padding-bottom: 2px; border-bottom: 1px solid transparent;
    transition: border-color var(--hs-dur-2) var(--hs-ease);
    white-space: nowrap;
}
.hm-card:hover .hm-card-count { border-bottom-color: var(--hs-blue); }
.hm-card-arrow { display: inline-block; transition: transform var(--hs-dur-2) var(--hs-ease); }
.hm-card:hover .hm-card-arrow { transform: translateX(3px); }
.hm-card-intro { display: block; font-size: 15px; line-height: 1.7; color: var(--hs-text-2); }

/* ==========================================================================
   404
   ========================================================================== */
.nf { padding: 60px 30px 120px; }
.nf-inner { max-width: 760px; margin: 0 auto; background-color: var(--hs-white); padding: 70px 40px; text-align: center; }
.nf-code { font-size: 70px; font-weight: 700; color: var(--hs-blue-light); line-height: 1; margin: 0 0 10px; }
.nf-title { font-size: 28px; color: var(--hs-text); margin-bottom: 16px; }
.nf-text { font-size: 16px; color: var(--hs-text-2); line-height: 1.8; margin-bottom: 30px; }
.nf-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.nf-actions .pd-btn { margin: 0; }

/* ==========================================================================
   页脚
   ========================================================================== */
.ft { background-color: var(--hs-white); border-top: 3px solid var(--hs-blue); }
.ft-main { padding: 50px 30px 40px; }
.ft-inner { max-width: var(--hs-header); margin: 0 auto; }
.ft-cols { display: grid; grid-template-columns: repeat(5, 1fr) 1.5fr; gap: 30px; }
.ft-title { font-size: 16px; font-weight: 700; color: var(--hs-text); margin-bottom: 16px; }
.ft-title a:hover { color: var(--hs-blue); }
.ft-list li { margin-bottom: 9px; }
.ft-list a { font-size: 15px; color: var(--hs-text-2); }
.ft-list a:hover { color: var(--hs-blue); }
.ft-contact li { display: flex; gap: 8px; font-size: 15px; color: var(--hs-text-2); align-items: baseline; }
/* 页脚搜索：全端可见（页头那个 ≤1200px 会隐藏），手机端的主要入口 */
.ft-search { display: flex; margin-top: 16px; }
.ft-search-input {
    flex: 1;
    min-width: 0;             /* 不加这行，flex 子项不会缩到内容宽度以下，窄屏会撑破列 */
    height: 36px;
    padding: 0 12px;
    border: 1px solid var(--hs-line-3);
    border-right: 0;
    border-radius: var(--hs-radius) 0 0 var(--hs-radius);
    font: inherit;
    font-size: 14px;
    color: var(--hs-text);
}
.ft-search-input:focus-visible { outline: 2px solid var(--hs-orange); outline-offset: -2px; }
.ft-search-btn {
    height: 36px;
    padding: 0 16px;
    border: 0;
    border-radius: 0 var(--hs-radius) var(--hs-radius) 0;
    background-color: var(--hs-blue);
    color: var(--hs-white);
    font-size: 14px;
}
.ft-search-btn:hover { background-color: var(--hs-blue); }
.ft-label { flex: 0 0 auto; color: var(--hs-text-3); }
.ft-social { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.ft-social a { font-size: 14px; color: var(--hs-text-3); border: 1px solid var(--hs-line-3); padding: 3px 10px; border-radius: var(--hs-radius); }
.ft-social a:hover { border-color: var(--hs-blue); color: var(--hs-blue); }

.ft-bottom { background-color: var(--hs-bg); padding: 20px 30px; }
.ft-bottom-inner { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: center; }
.ft-copy { font-size: 14px; color: var(--hs-text-3); }
.ft-legal { font-size: 14px; color: var(--hs-text-mute); }

/* ==========================================================================
   询盘表单（/inquiry、/contact 内嵌、以后的 AI 选型助手共用一套）
   --------------------------------------------------------------------------
   设计原则只有一条：**降低填写摩擦**。B2B 询盘的客户是在上班时间、
   拿手机或办公电脑随手填一次，任何多余的一步都会掉转化。所以：

     · 必填只有 3 个（姓名 / 邮箱 / 需求描述），其余全选填；
     · 品类和应用两个下拉是"帮销售定位"，不是"考核客户"，允许留空；
     · 从产品页进来时品类直接锁成标签显示，客户不用再选一次；
     · 输入框 44px 高、正文 15px，触屏不误触，桌面不显得虚。

   刻意不做成弹窗：老站弹窗里的表单对爬虫等于不存在，而且弹窗会挡住
   页面内容让客户没法核对型号。
   ========================================================================== */

.iq-page { padding: 0 30px 90px; }
.iq-page-inner { max-width: 940px; margin: 0 auto; background-color: var(--hs-white); padding: 40px; }
.iq-page-narrow { max-width: 720px; }

.iq-head { margin-bottom: 26px; }
.iq-title { font-size: 28px; line-height: 1.35; color: var(--hs-text); margin-bottom: 10px; word-break: break-word; }
.iq-intro { font-size: 16px; line-height: 1.7; color: var(--hs-text-2); margin: 0; }

.iq-panel { border-top: 1px solid var(--hs-line); padding-top: 26px; }

/* ---- 表单 ---- */
.iq-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px 24px; }
.iq-field { display: flex; flex-direction: column; min-width: 0; }
.iq-field-wide { grid-column: 1 / -1; }

.iq-label { font-size: 14px; color: var(--hs-text-2); margin-bottom: 7px; }
.iq-label em { color: var(--hs-orange); font-style: normal; margin-left: 2px; }

.iq-input {
    width: 100%;
    height: 44px;
    padding: 0 13px;
    font-size: 15px;
    font-family: inherit;
    color: var(--hs-text);
    background-color: var(--hs-white);
    border: 1px solid var(--hs-line-3);
    border-radius: var(--hs-radius);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.iq-input::placeholder { color: var(--hs-text-mute); }
.iq-input:focus {
    outline: none;
    border-color: var(--hs-blue);
    /* 用 box-shadow 画焦点环而不是 outline：老站的输入框聚焦后外框会被
       overflow 裁掉一半，看起来像"点不进去" */
    box-shadow: 0 0 0 3px rgba(1, 105, 178, .12);
}
.iq-textarea { height: auto; min-height: 140px; padding: 12px 13px; line-height: 1.7; resize: vertical; }

/* ★ #309（2026-09-25 JACK）：站内表单提交按钮统一放右侧 ——
   隐私说明排到最左（order:-1 + margin-right:auto 推开），「提交需求」贴最右。
   搜索类表单（.ft-search / .se-form）输入框 flex:1 占满 ⇒ 按钮本就贴右，无需动。 */
.iq-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; margin-top: 26px; justify-content: flex-end; }
.iq-submit {
    min-width: 190px;
    height: 48px;
    padding: 0 30px;
    font-size: 17px;
    font-family: inherit;
    color: var(--hs-white);
    background-color: var(--hs-orange);
    border: 1px solid var(--hs-orange);
    border-radius: var(--hs-radius);
    cursor: pointer;
    transition: background-color .2s ease, border-color .2s ease;
}
.iq-submit:hover { background-color: var(--hs-orange-dark); border-color: var(--hs-orange-dark); }
/* #309：privacy 不再 flex:1 撑满（那会把按钮推回最左）；order:-1 排到按钮左侧、
   margin-right:auto 把按钮推到最右。 */
.iq-privacy { font-size: 13px; color: var(--hs-text-mute); margin: 0; order: -1; margin-right: auto; }

/* ---- 从产品页进来：已确定的需求标签 ---- */
.iq-locked {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 22px;
    padding: 12px 16px;
    background-color: var(--hs-blue-light);
    border-left: 3px solid var(--hs-blue);
    font-size: 15px;
}
.iq-locked-label { color: var(--hs-text-2); font-size: 13px; }
.iq-locked-value { font-weight: 700; color: var(--hs-blue); }
.iq-locked-tag, .iq-locked-intent {
    font-size: 13px;
    color: var(--hs-text-2);
    background-color: var(--hs-white);
    border: 1px solid var(--hs-blue-light);
    border-radius: 999px;
    padding: 2px 10px;
}

/* ---- 型号清单：一次询价里客户勾了哪几个（台账 #266/#267） ----
   客户在列表页勾了 N 个型号、点「提交询价」后落到 /inquiry 看到的就是它。
   ★ 只读：增删在列表页的托盘里做，这里不提供第二套增减逻辑
     （两处都能改 = 清单有两个真相源，不一致时说不清以谁为准）。
   ★ 卡片语法照自家设计系统：1px 细边 + 3px 蓝顶边，与首页/列表卡片一致。 */
.iq-items {
    margin-bottom: 22px;
    border: 1px solid var(--hs-line);
    border-top: 3px solid var(--hs-blue);
}
.iq-items-head {
    margin: 0; padding: 12px 16px;
    border-bottom: 1px solid var(--hs-line);
    font-size: 14px; color: var(--hs-text-2);
}
.iq-items-head b { font-size: 16px; color: var(--hs-text); }
.iq-items-list { margin: 0; padding: 0; list-style: none; }
.iq-item {
    display: flex; align-items: baseline; gap: 10px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--hs-line);
    font-size: 14px;
}
.iq-item:last-child { border-bottom: 0; }
.iq-item-name { font-weight: 700; color: var(--hs-text); overflow-wrap: anywhere; }
.iq-item-name:hover { color: var(--hs-blue); }
/* 库里没有这个型号：**不去掉、不改写成错误**，只明显弱化。
   客户手抄错一个字符、或者问的是我们还没上架的型号，都属正常；
   「他到底问了什么」是销售要看到的信息，替他过滤掉等于替他做决定。 */
.iq-item-miss { font-weight: 400; color: var(--hs-text-mute); cursor: help; }
.iq-item-pkg { font-size: 12px; color: var(--hs-text-mute); }
.iq-items-note {
    margin: 0; padding: 10px 16px;
    border-top: 1px solid var(--hs-line);
    font-size: 13px; color: var(--hs-text-3);
}

/* ---- 错误提示：全站在顶部集中显示，不逐字段标红 ---- */
.iq-errors {
    margin-bottom: 20px;
    padding: 12px 16px;
    background-color: #fff4f2;
    border-left: 3px solid #d94a3d;
}
.iq-errors ul { margin: 0; padding-left: 18px; }
.iq-errors li { font-size: 14px; line-height: 1.8; color: #a33227; }

/* ---- 蜜罐：视觉移出可视区，但仍在 DOM 里（脚本会填它） ----
   不能用 display:none / visibility:hidden / type=hidden，相当一部分
   自动化脚本会主动跳过这些"明显是陷阱"的字段，蜜罐就白设了。 */
.iq-hp {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ---- 表单页底部兜底出口 ---- */
.iq-alt { margin: 20px 0 0; font-size: 14px; color: var(--hs-text-3); }
.iq-alt a { color: var(--hs-blue); text-decoration: underline; }

/* ---- 提交成功页 ---- */
.iq-done { text-align: center; padding: 26px 0 6px; }
.iq-done-mark {
    width: 62px; height: 62px; line-height: 62px;
    margin: 0 auto 20px;
    font-size: 32px; color: var(--hs-white);
    background-color: #2e9e5b;
    border-radius: 50%;
}
.iq-done-title { font-size: 26px; color: var(--hs-text); margin-bottom: 16px; }
.iq-done-text { font-size: 16px; line-height: 1.85; color: var(--hs-text-2); max-width: 620px; margin: 0 auto 12px; }
.iq-done-text a { color: var(--hs-blue); text-decoration: underline; }
.iq-done-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 16px; margin-top: 26px; }

/* ---- 联系页内嵌（写在 .ct 容器内部的第二种排版）---- */
.iq-embed { max-width: 940px; margin: 0 auto; padding: 0 40px 46px; }
.iq-embed .iq-panel { border-top: 1px solid var(--hs-line); }
.iq-embed-title { font-size: 24px; color: var(--hs-text); margin-bottom: 8px; }

/* ==========================================================================
   技术社区（/techforum）
   --------------------------------------------------------------------------
   布局：形态 tab（顶部通栏）+ 三栏（左 220 维度 / 中 自适应列表 / 右 300 侧栏）

   为什么左栏放「维度切换器」而不是常驻所有分类：
     应用 11 个子类 + 产品 35 个子类 = 46 个分类同时铺开，
     左栏会变成一堵 2000px 高的墙，读者根本扫不完。
     两个维度用 tab 切换（一次只展示一个维度），配合右侧「已选条件条」，
     读者任何时候都能看到自己选了什么、能一键清掉 —— 这就是「矩阵交叉」
     的可视化：两个维度各留一份已选状态，交叉结果在中栏。
   ========================================================================== */
.tf { max-width: calc(var(--hs-container) - 80px); margin: 0 auto; padding: 24px 0 60px; }

/* ---------- 页面主标题（H1）＝ 形态行首的「TechForum」 ----------
   栏目页必须有 h1：此前整页只有 h2，标题层级断裂，搜索引擎与 AI
   抓取时拿不到页面主题。
   2026-09-26 JACK：原独立大标题（.tf-title，技术社区/TechForum/形态名）
   整块移除 —— 该样式随之退役；形态行首「TechForum」放大到同等字号
   （26px/700）并升级为页面 H1，一块两用。 */
/* ---------- 形态 tab（#347，2026-09-26 JACK：照老站改纯文字 tab） ----------
   去边框药丸、去计数徽标 —— 老站就是一排纯文字：选中蓝字+蓝底线，hover 蓝字。
   链接仍是真实静态地址（SEO 不变）。
   2026-09-26 追加（JACK）：行首加粗「TechForum」标签；所有类别名加粗；
   类别间隙 +20%（28 → 33.6 ≈ 34px）。 */
.tf-shapes {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline; /* 26px 的 h1 标签与 15px 的 tab 按基线对齐，行高不受大字撑乱 */
    gap: 8px 34px;
    padding: 0 40px 16px;
    border-bottom: 1px solid var(--hs-line);
}
.tf-shapes-label {
    margin: 0; /* h1 的 UA 默认外边距必须归零，否则形态行被撑高 */
    font-size: 26px;
    font-weight: 700;
    line-height: 1;
    color: var(--hs-text-1);
}
.tf-shape {
    font-size: 15px;
    font-weight: 700;
    color: var(--hs-text-2);
    line-height: 30px;
    border-bottom: 2px solid transparent;
}
.tf-shape:hover { color: var(--hs-blue); }
.tf-shape.is-on { color: var(--hs-blue); border-bottom-color: var(--hs-blue); font-weight: 700; }
.tf-shape.is-on:hover { color: var(--hs-blue); }

.tf-shape-intro {
    padding: 16px 40px 0;
    color: var(--hs-text-3);
    font-size: 15px;
    margin: 0;
}

/* ---------- 三栏 ---------- */
.tf-wrap { display: flex; align-items: flex-start; gap: 28px; padding: 22px 40px 0; }

/* ---------- 表头筛选区（#343/#348，2026-09-26 JACK） ----------
   结构照产品页横向两行（每维一行：标签 + 横排一级 tab + | 分隔），
   皮肤照老站（#348=A）：标签 = 蓝色块白字，首项 All（点击清本维）。
   左栏 230px 维度切换器（.tf-side / .tf-dim* / .tf-group* / .tf-chip*）
   随本改造整体退役，维度切换 JS 一并删除（两维常驻表头，无需显隐）。
   交互：
   · 点击一级 tab = 筛选整组（#345=B）；
   · 鼠标移入一级 = 弹出该组全部二级（#346=A，纯 CSS hover/focus-within，
     二级是静态直出的真实 <a>；触屏无 hover ⇒ 窄屏选中组的面板平铺显示）；
   · 面板只列名字，无计数、无弱化（#349=A）。 */
.tf-tabs { background-color: var(--hs-white); padding: 6px 40px 14px; }
.tf-tabs-row { display: flex; gap: 16px; padding: 10px 0; border-top: 1px dashed var(--hs-line-2); align-items: center; }
.tf-tabs-row:first-child { border-top: 0; }
.tf-tabs-tip {
    flex: 0 0 96px;
    background-color: var(--hs-blue);
    color: var(--hs-white);
    font-size: 14px;
    line-height: 32px;
    text-align: center;
}
.tf-tabs-list { display: flex; flex-wrap: wrap; gap: 8px 12px; flex: 1 1 auto; min-width: 0; }
.tf-tabs-sep { color: var(--hs-text-3); line-height: 32px; user-select: none; }
.tf-tab-box { position: relative; display: inline-block; }
/* 2026-09-26 JACK：未选中的 tab 不加粗，选中才加粗（形态行的 700 不适用于这里） */
.tf-tab { display: inline-block; font-size: 15px; color: var(--hs-text-2); line-height: 32px; font-weight: 400; border-bottom: 2px solid transparent; }
.tf-tab:hover { color: var(--hs-blue); }
.tf-tab.is-active { color: var(--hs-blue); border-bottom-color: var(--hs-blue); font-weight: 700; }
/* 二级 hover 面板：平时隐藏，移入一级 tab 弹出。
   白底 + 1px 线 + 2px 蓝顶边 —— 「卡片 = 1px 边 + 蓝顶边」设计系统语法的小控件版。 */
.tf-drop {
    display: none;
    position: absolute;
    top: 100%;
    left: -14px;
    z-index: 30;
    min-width: 176px;
    padding: 6px 0;
    background-color: var(--hs-white);
    border: 1px solid var(--hs-line);
    border-top: 2px solid var(--hs-blue);
}
.tf-tab-box:hover .tf-drop,
.tf-tab-box:focus-within .tf-drop { display: block; }
.tf-drop-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 7px 14px;
    font-size: 14px;
    color: var(--hs-text-2);
    line-height: 1.5;
    white-space: nowrap;
}
.tf-drop-item:hover { background-color: var(--hs-blue-light); color: var(--hs-blue); }
.tf-drop-item.is-active { color: var(--hs-blue); font-weight: 700; }
/* #349（2026-09-26 JACK）：面板只列名字 —— 计数与 0 篇弱化（原 is-zero /
   tf-drop-count）整体去除，照老站「没有杂乱信息」。 */

/* ---------- 中栏 ---------- */
.tf-main { flex: 1 1 auto; min-width: 0; }

.tf-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--hs-line);
}
.tf-picked { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.tf-picked-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background-color: var(--hs-blue-light);
    border-radius: var(--hs-radius);
    font-size: 14px;
    color: var(--hs-blue);
}
.tf-picked-tag:hover { background-color: var(--hs-blue-light); }
.tf-picked-dim { color: var(--hs-text-mute); font-size: 13px; }
.tf-picked-name { font-weight: 700; }
.tf-picked-x { font-size: 15px; line-height: 1; }
.tf-picked-hint { color: var(--hs-text-mute); font-size: 14px; }

.tf-sorts { display: flex; gap: 4px; }
.tf-sort {
    padding: 5px 12px;
    border-radius: var(--hs-radius);
    font-size: 14px;
    color: var(--hs-text-2);
}
.tf-sort:hover { background-color: var(--hs-bg); color: var(--hs-blue); }
.tf-sort.is-on { background-color: var(--hs-blue); color: var(--hs-white); font-weight: 700; }
.tf-sort.is-on:hover { color: var(--hs-white); }

.tf-cross-tip {
    margin: 0 0 14px;
    padding: 9px 14px;
    background-color: #fff8ec;
    border-left: 3px solid var(--hs-orange);
    color: #8a5a00;
    font-size: 14px;
}

/* ---------- 文章卡片 ---------- */
.tf-list { display: grid; gap: 16px; }
.tf-card { background-color: var(--hs-white); border: 1px solid var(--hs-line); transition: box-shadow .2s ease, transform .2s ease; }
.tf-card:hover { box-shadow: 0 4px 14px rgba(1, 105, 178, .1); transform: translateY(-2px); }
.tf-card-link { display: flex; gap: 18px; padding: 18px; }
.tf-card-media { flex: 0 0 210px; width: 210px; overflow: hidden; border-radius: var(--hs-radius); }
.tf-card-media img { display: block; width: 100%; height: 130px; object-fit: cover; }
.tf-card-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1 1 auto; }
.tf-card-title { font-size: 17px; font-weight: 700; color: var(--hs-text); line-height: 1.45; } /* 2026-10-02 JACK：19→17 小一号（预览截图 tf-title-after-17px.png 拍板 A），移动端断点 17px 不动 */
.tf-card:hover .tf-card-title { color: var(--hs-blue); }
.tf-card-intro {
    color: var(--hs-text-3);
    font-size: 15px;
    line-height: 1.65;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.tf-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.tf-tag {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--hs-radius);
    font-size: 13px;
    line-height: 1.6;
}
.tf-tag-app { background-color: var(--hs-blue-light); color: var(--hs-blue); }
.tf-tag-prod { background-color: #f0f0f0; color: var(--hs-text-3); }
a.tf-tag-prod:hover { background-color: var(--hs-blue); color: var(--hs-white); }
.tf-card-meta { color: var(--hs-text-mute); font-size: 13px; }
.tf-recomm { color: var(--hs-orange); font-weight: 700; }

.tf-empty {
    padding: 40px 20px;
    background-color: var(--hs-white);
    border: 1px dashed var(--hs-line-3);
    color: var(--hs-text-3);
    text-align: center;
}
.tf-empty-cta { margin: 16px 0 0; text-align: center; }

.tf-pager { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 26px; }

/* ---------- 右栏 ---------- */
.tf-aside { width: 300px; flex: 0 0 300px; display: grid; gap: 16px; }
/* 侧栏首位广告窗（2026-09-26 JACK）：去掉全局 .ad-side 的下外边距（间距交给 grid gap 管） */
.tf-aside .ad-side { margin: 0; }
.tf-box { background-color: var(--hs-white); border: 1px solid var(--hs-line); padding: 16px 18px; }
.tf-box-title {
    margin: 0 0 12px;
    padding-bottom: 9px;
    border-bottom: 2px solid var(--hs-blue);
    font-size: 17px;
    color: var(--hs-text);
}
.tf-box-list { display: grid; gap: 11px; }
.tf-box-list li { padding-bottom: 11px; border-bottom: 1px dashed var(--hs-line-2); }
.tf-box-list li:last-child { padding-bottom: 0; border-bottom: 0; }
.tf-box-t {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 15px;
    color: var(--hs-text-2);
    line-height: 1.55;
}
.tf-box-list a:hover .tf-box-t { color: var(--hs-blue); }
.tf-box-d { display: block; margin-top: 4px; color: var(--hs-text-mute); font-size: 13px; }
.tf-box-empty { color: var(--hs-text-mute); font-size: 14px; margin: 0; }
.tf-cta-box { display: block; }

/* ---------- 详情页（#352=B，2026-09-26 JACK：两栏化） ----------
   左 = 正文白卡（flex 撑满），右 = 350px 侧栏（相关产品 + 相关阅读）。
   左右内边距 40 与列表页 .tf-wrap 对齐；1025~1618 的右缘 82px 净空
   由文件末尾白名单统一接管（.tf-detail-grid 已入列）。
   侧栏空态（无产品 tag 且无相关文章）时模板不渲染 aside ⇒
   grid 只剩正文一列，自动回满宽 —— 不需要任何额外样式分支。 */
.tf-detail-grid { display: flex; align-items: flex-start; gap: 24px; padding: 22px 40px 0; }
.tf-detail-grid .tf-article { flex: 1 1 auto; min-width: 0; }
.tf-detail-aside { flex: 0 0 350px; width: 350px; display: flex; flex-direction: column; gap: 20px; }
/* 侧栏顶部广告窗（2026-09-26 JACK：原文末广告图上侧栏）：素材 350×124
   恰为侧栏整宽 —— 去掉全局 .ad-side 的下外边距（间距交给 aside 的 gap 管）。 */
.tf-detail-aside .ad-side { margin: 0; }

/* 侧栏卡：原为设计系统 ②（1px 线 + 3px 蓝顶边）。
   2026-09-26 JACK 圈图直改：3px 蓝线从盒顶下移到「标题与内容之间」
   （挂在 .tf-side-h 的下边框上）—— 盒顶回归纯 1px 线。 */
.tf-side-box { background-color: var(--hs-white); border: 1px solid var(--hs-line); padding: 18px 20px 16px; }
.tf-side-h { margin: 0; font-size: 17px; font-weight: 700; color: var(--hs-text); padding-bottom: 8px; border-bottom: 3px solid var(--hs-blue); }
.tf-side-cat { margin: 10px 0 0; font-size: 13px; color: var(--hs-text-3); }

/* 相关产品：8 行紧凑行（型号 + 封装与两个关键参数） */
.tf-pick-list { list-style: none; margin: 6px 0 0; padding: 0; }
.tf-pick { border-bottom: 1px solid var(--hs-line); }
.tf-pick:last-child { border-bottom: 0; }
.tf-pick a { display: block; padding: 10px 0; }
.tf-pick-model { display: block; font-size: 14px; font-weight: 700; color: var(--hs-text); }
.tf-pick a:hover .tf-pick-model { color: var(--hs-blue); }
.tf-pick-meta { display: block; margin-top: 3px; font-size: 12.5px; color: var(--hs-text-3); line-height: 1.5; }
.tf-side-more { display: block; margin-top: 12px; font-size: 13px; font-weight: 700; color: var(--hs-blue); }
.tf-side-more:hover { text-decoration: underline; }

/* 相关阅读缩略卡（#342 卡片化随本批落地）：无封面回退与列表卡同一张默认图 */
.tf-rel-cards { display: flex; flex-direction: column; gap: 14px; margin-top: 12px; }
.tf-rel-card { display: block; }
.tf-rel-thumb { display: block; border: 1px solid var(--hs-line); }
.tf-rel-thumb img { display: block; width: 100%; aspect-ratio: 13 / 8; object-fit: cover; }
.tf-rel-t { display: block; margin-top: 8px; font-size: 14px; line-height: 1.55; color: var(--hs-text); font-weight: 700; }
.tf-rel-card:hover .tf-rel-t { color: var(--hs-blue); }
.tf-rel-d { display: block; margin-top: 4px; font-size: 12.5px; color: var(--hs-text-mute); }

/* .tf-detail-tools（文末工具条）已退役：分享 2026-09-26 上提标题下方、
   文末广告卡同日按 JACK 指令移除 —— 详情页尾部不再有这两块。
   全局 .ad-side / .ad-share 样式（1611 行起）仍服务列表页侧栏，不动。 */

/* 标题下的分享行（2026-09-26 JACK：从文末上提）。
   复用 ad_share.html 的 .ad-share 结构，但这里是正文白卡内部 ——
   去掉全局样式里的白底/大内边距/下边距，压成一行内联排布。 */
.tf-article-share { margin: 8px 0 16px; }
.tf-article-share .ad-share { background: none; padding: 0; margin: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 12px 18px; }
.tf-article-share .ad-share-title { margin: 0; font-size: 15px; }

/* 返回顶部（2026-09-26 JACK：文章尾部右下） */
.tf-article-foot { display: flex; justify-content: flex-end; margin-top: 22px; }
.tf-backtop {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--hs-line);
    background-color: var(--hs-white);
    font-size: 13px; color: var(--hs-text-2);
}
.tf-backtop:hover { border-color: var(--hs-blue); color: var(--hs-blue); }
.tf-backtop-ico { font-size: 12px; line-height: 1; }
.tf-article { background-color: var(--hs-white); border: 1px solid var(--hs-line); padding: 34px 40px 38px; }
.tf-article-head { margin-bottom: 22px; }
.tf-article-kicker { margin: 0 0 10px; font-size: 14px; }
.tf-article-kicker a { color: var(--hs-blue); font-weight: 700; }
.tf-article-title { font-size: 32px; line-height: 1.35; color: var(--hs-text); margin-bottom: 12px; }
.tf-article-lede { color: var(--hs-text-3); font-size: 17px; margin: 0 0 14px; }
.tf-article-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }
.tf-article-meta { color: var(--hs-text-mute); font-size: 14px; margin: 0; }
.tf-cover { margin: 0 0 24px; }
.tf-cover img { display: block; width: 100%; border-radius: var(--hs-radius); }
.tf-lead {
    margin: 0 0 26px;
    padding: 16px 20px;
    background-color: var(--hs-bg);
    border-left: 3px solid var(--hs-blue);
    color: var(--hs-text-2);
    font-size: 16.5px;
    line-height: 1.75;
}
/* .tf-related（原文末相关阅读文字列表块）已随 #352=B 退役 ——
   相关阅读改为侧栏缩略卡（.tf-rel-card），样式见上。 */

/* 正文富文本：与内容栏目的 ct-richtext 共用排版，补上技术社区特有的元素
   （参数表、代码、提示块）—— 应用方案类文章大量使用这三类元素 */
.tf-richtext { font-size: 16.5px; line-height: 1.85; color: var(--hs-text); }
.tf-richtext h2 { margin: 34px 0 14px; padding-left: 12px; border-left: 4px solid var(--hs-blue); font-size: 23px; }
.tf-richtext h3 { margin: 26px 0 12px; font-size: 19px; color: var(--hs-text); }
.tf-richtext h4 { margin: 20px 0 10px; font-size: 17px; }
.tf-richtext p { margin: 0 0 1.1em; }
.tf-richtext img { display: block; max-width: 100%; margin: 18px auto; border-radius: var(--hs-radius); }
.tf-richtext table { width: 100%; margin: 20px 0; border-collapse: collapse; font-size: 15px; }
.tf-richtext th, .tf-richtext td { padding: 10px 12px; border: 1px solid var(--hs-line-3); text-align: left; }
.tf-richtext th { background-color: var(--hs-blue-light); font-weight: 700; }
.tf-richtext tr:nth-child(even) td { background-color: #fafcfe; }
.tf-richtext ul, .tf-richtext ol { margin: 0 0 1.1em; padding-left: 1.5em; }
.tf-richtext ul { list-style: disc; }
.tf-richtext ol { list-style: decimal; }
.tf-richtext li { margin-bottom: .45em; }
.tf-richtext blockquote {
    margin: 20px 0;
    padding: 12px 18px;
    background-color: #fff8ec;
    border-left: 3px solid var(--hs-orange);
    color: #7a5100;
}
.tf-richtext pre {
    margin: 20px 0;
    padding: 14px 16px;
    background-color: #1f2b38;
    color: #e6edf3;
    border-radius: var(--hs-radius);
    overflow-x: auto;
    font-size: 14px;
}
.tf-richtext code { font-family: Consolas, Monaco, 'Courier New', monospace; }
.tf-richtext a { color: var(--hs-blue); text-decoration: underline; text-underline-offset: 2px; }

/* ==========================================================================
   响应式
   --------------------------------------------------------------------------
   老站靠 30 多个 @media 逐像素覆盖，这里只保留 5 个语义断点。
   ========================================================================== */

/* 窄桌面：版心开始压缩，但字号不缩 —— 这是与老站最大的体验差别 */
@media (max-width: 1440px) {
    .pd-media { width: 320px; flex-basis: 320px; }
    .pd-aside { width: 320px; flex-basis: 320px; }
}

@media (max-width: 1200px) {
    /* 顶栏搜索已删除（#160 A），这里原本的 `.hd-search{display:none}` 一并移除。 */
    .hd-menu-link { padding: 0 13px; font-size: 17px; }
    .pd-hero-inner { padding: 40px 30px; }
    .pd-sec-head { margin-left: 30px; margin-right: 30px; padding-left: 0; padding-right: 0; }
    .pd-sec-body, .pd-aside-cta { padding-left: 30px; padding-right: 30px; }
    .pd-body-inner { gap: 26px; }
    .pd-aside { width: 300px; flex-basis: 300px; }
    .ct-list { grid-template-columns: repeat(2, 1fr); }
    .ft-cols { grid-template-columns: repeat(3, 1fr) 1.5fr; }
    .hd-mega-cols { grid-template-columns: repeat(3, 1fr); }
    .cl-filter { padding-left: 30px; padding-right: 30px; }
    /* 技术社区：右栏收窄，左栏不变（维度切换器是可点的，不能压太窄） */
    .tf-wrap { padding-left: 30px; padding-right: 30px; }
    .tf-shapes, .tf-shape-intro { padding-left: 30px; padding-right: 30px; }
    .tf-aside { width: 270px; flex-basis: 270px; }
    .tf-card-media { flex-basis: 180px; width: 180px; }
}

/* 平板：第一屏改为上下结构（图在上、参数在下），这也是老站在 1000px 附近的做法 */
@media (max-width: 1024px) {
    .hd-nav { display: none; }
    .hd-burger { display: block; }
    .hd-menu { display: none; }

    /* 移动端菜单展开后：整屏抽屉，二级菜单改为点击展开 */
    .hd-nav.is-open {
        display: block;
        position: fixed;
        top: 0; right: 0;
        width: min(320px, 86vw);
        height: 100vh;
        background-color: var(--hs-white);
        box-shadow: -6px 0 24px rgba(0, 0, 0, .18);
        overflow-y: auto;
        padding: 56px 0 30px;
        z-index: 200;
    }
    .hd-nav.is-open .hd-menu { display: block; }
    .hd-nav.is-open .hd-menu-item { display: block; }
    .hd-nav.is-open .hd-menu-link {
        height: auto; line-height: 1.5; padding: 14px 22px; font-size: 17px; font-weight: 400;
        border-bottom: 1px solid var(--hs-line-2);
    }
    .hd-nav.is-open .hd-sub,
    .hd-nav.is-open .hd-mega {
        position: static; transform: none; opacity: 1; visibility: visible;
        box-shadow: none; border-top: 0; display: none; width: 100%; padding: 8px 0 12px;
    }
    .hd-nav.is-open .hd-menu-item.is-open > .hd-sub,
    .hd-nav.is-open .hd-menu-item.is-open > .hd-mega { display: block; }
    .hd-nav.is-open .hd-mega-cols { grid-template-columns: 1fr; gap: 14px; }
    .hd-nav.is-open .hd-mega-inner { padding: 0 22px; }
    .hd-nav.is-open .hd-sub li a,
    .hd-nav.is-open .hd-mega-list li a { padding: 8px 22px; font-size: 15px; }

    .pd-media { width: 100%; flex-basis: 100%; }
    .pd-info { max-width: 100%; }
    .pd-body-inner { flex-direction: column; }
    .pd-aside { width: 100%; flex-basis: 100%; }
    .pd-spec { width: 33.3333%; }
    /* 1024px 视口的容器还有 964px，3 列每列 ~310px。
       原来是 2 列 ⇒ 32 个产品分类堆成 721px 的长条。
       #374：hm-grid 已改 flex 自适应栅格，这里把每卡压回 3 列宽
       （.hm-grid.hm-adapt 同为 0,2,0 特异度、且写在 .wK 之后 ⇒ 覆盖生效）。 */
    .hm-grid.hm-adapt > li { width: calc((100% - 2 * var(--gw)) / 3); }
    .ct-list { grid-template-columns: repeat(2, 1fr); }
    /* 平板起筛选条继续满宽横排，只是取值面板减少分栏、放宽列宽 */
    .cl-filter { padding-left: 30px; padding-right: 30px; }
    .cl-overview { padding: 30px; }
    .ft-cols { grid-template-columns: repeat(2, 1fr); }

    /* 技术社区平板：右栏落到中栏下方（两个区块并排）。
       #343 起筛选区上移为表头横排（.tf-tabs 自带窄屏适配），
       原 230px 左栏维度切换器已不存在。 */
    .tf-wrap { flex-wrap: wrap; }
    .tf-main { flex: 1 1 320px; }
    .tf-aside {
        width: 100%; flex-basis: 100%;
        grid-template-columns: repeat(2, 1fr);
    }
    .tf-cta-box { grid-column: 1 / -1; }
    .tf-article { padding: 26px 28px 30px; }
    .tf-article-title { font-size: 27px; }
    /* #352=B：详情页两栏 → 平板改上下堆叠（正文在上、侧栏在下）。
       侧栏两个盒子在宽屏里并排成两列（相关产品 + 相关阅读各占一半）。 */
    .tf-detail-grid { flex-direction: column; gap: 20px; }
    .tf-detail-aside {
        width: 100%; flex-basis: auto;
        display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px;
    }
}

@media (max-width: 768px) {
    /* align-items 用默认的 stretch：flex-start 会让子项按「内容宽度」收缩，
       长 slogan 在小屏上会撑破容器，把整页拉出横向滚动条（移动友好性硬伤） */
    .hd-top-inner { flex-direction: column; align-items: stretch; gap: 6px; padding: 8px 20px; }
    /* ⚠ .hm 从这条里拿掉，改走 --hm-gutter 变量（见文件顶部 .hm 规则）。
       若继续在这里硬写 padding-left/right: 20px，hero 的负外边距仍按 --hm-gutter=30
       计算 ⇒ 左右各多出 10px，直接撑出横向滚动条。 */
    .hd-inner, .bc, .pd, .nf { padding-left: 20px; padding-right: 20px; }
    .hm { --hm-gutter: 20px; --hm-pad: 20px; }
    .pd-hero { padding: 14px 0 26px; }
    .pd-hero-inner { padding: 20px 18px; gap: 22px; }
    .pd-title { font-size: 22px; }
    .pd-spec { width: 50%; font-size: 15px; }
    /* 窄屏：按钮改为等宽撑满（对齐已在基线上统一为靠左，#102 修订） */
    .pd-actions { gap: 5px; }
    .pd-btn { min-width: 0; flex: 1 1 auto; margin: 0; }
    .pd-sec-head { margin-left: 18px; margin-right: 18px; padding-left: 0; padding-right: 0; }
    .pd-sec-body, .pd-app-list, .pd-aside-cta, .pd-app-more { padding-left: 18px; padding-right: 18px; }   /* §143：组内 .pd-related 已删（模板零引用） */
    .pd-sec-title { font-size: 19px; line-height: 56px; }
    .pd-sheet-card { flex-wrap: wrap; gap: 12px; padding: 14px 16px; }
    .pd-sheet-dl { flex: 1 1 100%; min-width: 0; }
    /* #306：A4 比例全档生效（aspect-ratio 在基础规则里），窄档定高 440px 退役。 */
    .cl-head, .cl-tabs, .cl-toolbar, .cl-pager { padding-left: 18px; padding-right: 18px; }
    .cl-body { padding-left: 18px; padding-right: 18px; }
    .cl-filter { padding-left: 18px; padding-right: 18px; }
    .cl-filter-title { display: none; }   /* 窄屏省掉标题，chips 自带语义 */
    .cl-filter-bar { gap: 8px; padding: 10px 0; }
    .cl-facet-values { columns: 2 140px; max-height: 260px; }
    .cl-overview { padding: 24px 18px; }
    .ct-head, .ct-subs, .ct-body, .ct-list-wrap, .ct-pager, .ct-related, .ct-cta { padding-left: 18px; padding-right: 18px; }
    .ct-title { font-size: 23px; }
    .ct-list { grid-template-columns: 1fr; gap: 16px; }
    /* 招聘卡片：窄屏改为上下堆叠，学历标签移到标题下方 */
    .jb-card-link { flex-direction: column; gap: 12px; padding: 18px 18px; }
    .jb-card-side { flex-direction: row; align-items: center; gap: 14px; width: 100%; justify-content: space-between; }
    .ct-cover, .ct-detail .ct-richtext { padding-left: 18px; padding-right: 18px; }
    .ct-lead { margin-left: 18px; margin-right: 18px; }
    /* ⚠ .hm-cats 这一档**不写在这里**：本块出现在下方 @1024 块之前，
       而 390 视口下 @768 与 @1024 会同时命中、由靠后的那条胜出 ——
       写在这里会被 @1024 的 32px 顶掉（实测 390 时上下内边距变成 32 vs .hm-sec 的 24）。
       统一放在文件末尾与 .hm-sec 同一个 @768 / @480 块里，保证严格升序。 */
    .hm-hero { padding: 40px calc(var(--hm-pad) + var(--hm-gutter)) 34px; }
    .hm-title { font-size: 27px; }
    /* 产品分类 32 项：768 时容器还有 ~688px，两列每列 330px 完全放得下。
       原来是 1fr（单列）⇒ 32 行堆成 1,286px 的长条，比手机版还长。
       真正的单列留到 ≤560（见文件末尾的 “紧凑断点”）。 */
    .hm-grid { grid-template-columns: repeat(2, 1fr); }
    .ft-cols { grid-template-columns: repeat(2, 1fr); gap: 22px; }
    .ft-bottom-inner { flex-direction: column; align-items: flex-start; }
    /* 询盘表单：窄屏单列。姓名/邮箱并排两列在手机上会把邮箱框压到
       190px 以下，@ 后面看不见，客户打错自己也不知道。 */
    .iq-page { padding: 0 18px 60px; }
    .iq-page-inner { padding: 24px 18px; }
    .iq-embed { padding: 0 18px 34px; }
    .iq-grid { grid-template-columns: 1fr; gap: 16px; }
    .iq-title { font-size: 22px; }
    .iq-done-title { font-size: 21px; }
    .iq-foot { flex-direction: column; align-items: stretch; }
    .iq-submit { width: 100%; }

    /* 技术社区手机：筛选区改表头横排（#343），维度 tip 独占一行、
       tab 折行；中栏单列，右栏区块单列堆叠 */
    .tf { padding: 16px 0 40px; }
    .tf-shapes { padding: 0 18px 12px; gap: 6px 24px; }
    .tf-shapes-label { font-size: 22px; }
    .tf-shape { font-size: 14px; line-height: 28px; }
    .tf-shape-intro { padding: 14px 18px 0; }
    .tf-tabs { padding: 0 18px 8px; }
    .tf-tabs-row { flex-direction: column; align-items: flex-start; gap: 2px; }
    .tf-tabs-tip { flex-basis: auto; padding: 0 14px; }
    .tf-tabs-sep { display: none; }
    /* 触屏无 hover：选中组的二级面板改为平铺显示（非选中组仍藏 ——
       链接照样在 HTML 里，爬虫不受影响） */
    .tf-drop { position: static; min-width: 0; width: 100%; border-top-width: 1px; }
    .tf-tab-box.is-active .tf-drop { display: block; }
    .tf-wrap { flex-direction: column; gap: 18px; padding: 18px 18px 0; }
    .tf-main { width: 100%; flex-basis: auto; }
    .tf-aside { width: 100%; flex-basis: auto; grid-template-columns: 1fr; }
    .tf-bar { flex-direction: column; align-items: flex-start; gap: 10px; }
    .tf-card-link { flex-direction: column; gap: 12px; padding: 14px; }
    .tf-card-media { flex-basis: auto; width: 100%; }
    .tf-card-media img { height: 170px; }
    .tf-card-title { font-size: 17px; }
    .tf-article { padding: 20px 18px 24px; }
    .tf-article-title { font-size: 23px; }

    /* news 行式列表手机：图上文下（§147） */
    .ct-newslist { padding: 0 18px; }
    .ct-news-link { flex-direction: column; gap: 12px; padding: 16px 0; }
    .ct-news-media { flex-basis: auto; width: 100%; }
    .tf-lead { padding: 13px 15px; font-size: 15.5px; }
    /* #352=B：手机上侧栏两列退回单列，内边距与 .tf-wrap 同步收窄 */
    .tf-detail-grid { padding: 18px 18px 0; }
    .tf-detail-aside { grid-template-columns: 1fr; gap: 16px; }
    .tf-richtext { font-size: 15.5px; }
    .tf-richtext h2 { font-size: 20px; }
    .tf-richtext h3 { font-size: 17.5px; }
    /* 宽参数表在手机上是唯一会横向溢出的元素 */
    .tf-richtext table { display: block; overflow-x: auto; white-space: nowrap; }
}

@media (max-width: 480px) {
    .ct-list { grid-template-columns: 1fr; }
    .ft-cols { grid-template-columns: 1fr; }
    .pd-spec { width: 100%; }
    .ct-cta { flex-direction: column; align-items: flex-start; }
    .ct-cta .pd-btn { width: 100%; }
    .iq-locked { flex-direction: column; align-items: flex-start; }
    .iq-done-actions { flex-direction: column; }
    .iq-done-actions .pd-btn { width: 100%; margin-right: 0; }
}

/* ==========================================================================
   广告位（hs_ad_slot / hs_ad_item）
   渲染点见 view/public/ad_banner.html（内页横幅）、view/public/ad_side.html（右栏广告+分享）、
   view/index/index.html（首页 hero / 快捷链接 / 中部横幅）。

   ⚠ 所有位都是「有素材才输出」—— 每条规则都必须能承受「这个元素根本不存在」，
     不能靠给空元素兜底高度来撑版面（那会在没有素材时留一块空白）。
   ⚠ 图上叠字的对比度不依赖图片本身：文字加 text-shadow，section 给深色底兜底，
     否则运营传一张浅色图，标题就看不见了。
   ========================================================================== */

/* ---- 首页主横幅：图上叠字 + CSS scroll-snap 轮播（不依赖 JS） ---- */
.hm-hero.is-media { padding: 0; overflow: hidden; background-color: var(--hs-blue-dark); }
.hm-hero-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.hm-hero-track::-webkit-scrollbar { display: none; }
.hm-hero-slide {
    position: relative; flex: 0 0 100%; min-height: 380px;
    display: flex; align-items: center;
    padding: 70px calc(var(--hm-pad) + var(--hm-gutter)) 60px; scroll-snap-align: start;
}
.hm-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hm-hero-slide .hm-inner { position: relative; z-index: 1; width: 100%; }
.hm-hero.is-media .hm-title,
.hm-hero.is-media .hm-lede,
.hm-hero.is-media .hm-hero-intro,
.hm-hero.is-media .hm-stat { color: var(--hs-white); text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
.hm-hero.is-media .hm-lede { max-width: 820px; }
.hm-hero-intro { font-size: 16px; line-height: 1.8; color: var(--hs-text-2); max-width: 900px; margin-bottom: 14px; }

/* §143（2026-09-28）：首页快捷链接 .hm-quick-* 四条规则已删 —— 模板零引用
   （旧版首页迭代遗留，扫描器+grep+DB 富文本三重核实），渲染不受影响。 */

/* ---- 首页中部横幅 ----
   ★★ 2026-09-20（JACK：「背景的宽度不一致」）：本块原来是**唯一一个没有左右内边距**
     的区块（线上是裸的 `margin-bottom: 30px`）。实测后果（1534 视口 / 中间栏宽度
     见下面那条注释）：
       `.hm-mid > .hm-inner` = [39.5 .. 1479.5]（宽 1440 = 命中 --hs-container 上限）
       同时其它所有区块的内容列 = [70 .. 1437]
     ⇒ 中部横幅的图片**比卡片列左凸 30.5px、右凸 42.5px**，是整页最扎眼的一处错位；
       1440 档因为容器刚好等于上限而不明显，一宽过版心就露出来。
   ★ 修法：给它和 `.hm-cats` / `.hm-sec` **完全相同**的左右内边距（`--hm-pad`），
     并在文件末尾的右让位块里一起加 12px ⇒ 图片外框 = 卡片列 = AI 条 = 区块版心。
   ⚠ 必须用变量而不是写死 40px：四档 media 里 `--hm-pad` 会一起变。
   ⚠ `.hm-mid` 仍然不带白底 —— 它就是一张图，不是区块。 */
.hm-mid { margin-bottom: 30px; padding: 0 var(--hm-pad); }
.hm-mid-item + .hm-mid-item { margin-top: 12px; }
/* 定位上下文 + overflow 裁切：叠字与箭头挂在这上面，图片 hover 放大时也不能溢出圆角/边框。
   background-color 兜底：图没加载出来（网速慢 / 素材被删）时是一块深蓝，不是一片白。 */
.hm-mid-link { position: relative; display: block; overflow: hidden; background-color: var(--hs-blue-dark); }
/* ★★ 2026-09-19 JACK 指令：banner 高度压到原来的 3/4。
   ★ 为什么一定要写 aspect-ratio（而不是只写 height）：这是一条**通栏**广告位，
     图片带 loading="lazy"，滚动到它之前不会加载 —— 而 <img> 未加载时高度是 0，
     等图到了再撑开，页面就会在用户眼前跳一下（CLS）。写上比例后，加载前就占好位置。
   素材 hs_asset #1270 是 1600 × 300（比例 5.33），@1440 容器 1380 时高 259px；
   目标 = 259 × 0.75 ≈ 194px ⇒ 比例要写成 1380 / 194 ≈ 7.11，即 1600 / 225。
   配合 object-fit: cover 会**上下各裁 37.5px**（共裁掉 25%）。
   —— 已先把裁切后的图导出来目视核对（analysis/shots/hero_check/
      mid-banner-cropped-1600x225.png）：图内的居中文字
      「Production Workshop / Precision · Automation · Reliability」恰在垂直中线，
      裁切后**完整保留**，被切掉的只是机台顶部与地面，无内容损失。
   ⚠ 换图必须重新核对：新素材若把文字放得更高或更低，居中裁切就会切到字。
      1600×130 是广告位定义 hs_ad_slot#3.image_spec 里写的规格，素材实际是 1600×300
      （该定义是错的，另见台账）。
   ★ 这里不必再配 max-height：它是通栏、永远 1 列，宽度只跟容器走（最大 1380），
     不存在"列数一少就把图拔高"的情形 —— 那条规则是给网格图用的。 */
.hm-mid-img {
    display: block; width: 100%; height: auto;
    aspect-ratio: 1600 / 225; object-fit: cover;
    /* hover 时轻微推近。0.6s + 自定义缓动是刻意的：横幅大，快了像闪一下。 */
    transition: transform .6s cubic-bezier(.2, .6, .2, 1);
}

/* ★★★ 2026-09-19 JACK #167 选 **A + B 都做**：图上叠字 + 箭头按钮 + 悬停态
   ────────────────────────────────────────────────────────────────────────
   改之前的形态 = 图下面跟一行 15px 灰字（`.hm-mid-text` 原样式）。两个问题：
     ① **看不出能点**：整条是 <a>，但视觉上是"图片 + 一行说明文字"，
        和旁边的正文没区别，用户不会去点；
     ② 说了两件事：图是"我们的产线"，灰字是"把参数发给我们"，
        没有把"这就是一个入口"这件事讲清楚。
   叠字之后：一句大字压在图上，右侧一个圆形箭头按钮，整条 = 一个广告位。

   ⚠ 叠字**只在有图时**才绝对定位（靠 `.is-media`）：没图时若还绝对定位，
     父容器高度是 0，文字会飘到父容器外面、和上一块内容重叠。见文件末尾
     `.hm-mid-link:not(.is-media) .hm-mid-text` 那条兜底。
   ⚠ 遮罩用**渐变**而不是整条深色横条：图是通栏长条（@1440 高 194px），
     整条压深会吃掉一半画面；渐变只压住文字所在的下沿，右上方保持干净。
   ⚠ 文案与箭头之间用 `space-between`：箭头**永远贴右**，中文句子长短不影响它的位置。 */
.hm-mid-link.is-media .hm-mid-text {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 30px 34px 18px;
    font-size: 19px; line-height: 1.4; font-weight: 600;
    color: var(--hs-white);
    background-image: linear-gradient(to top,
        rgba(4, 12, 26, .88) 0%, rgba(4, 12, 26, .62) 45%, rgba(4, 12, 26, 0) 100%);
    text-shadow: 0 1px 6px rgba(0, 0, 0, .5);
}
/* 没图时的兜底：回到"文字 + 右侧箭头"的深色条，不再是浮在图上的一层。
   ⚠ 这里也用 flex（不是 block）—— 因为箭头 `flex:none` 只有在 flex 容器里才拿得到
   40×40；放在 display:block 的 span 里它退回 inline，宽高直接失效、缩成一个小方块。
   两种形态（有图/无图）共用同一份箭头样式，是这个 flex 的唯一理由。 */
.hm-mid-link:not(.is-media) .hm-mid-text {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 16px 20px;
    background-color: var(--hs-blue-dark); color: var(--hs-white);
    font-size: 17px; line-height: 1.6; font-weight: 600;
}

/* 圆形箭头按钮：href 存在才由模板输出（没有链接时一个可点的圆圈是骗人的） */
.hm-mid-go {
    position: relative; flex: none;
    width: 40px; height: 40px; border-radius: 50%;
    background-color: rgba(255, 255, 255, .14);
    border: 1px solid rgba(255, 255, 255, .55);
    transition: background-color .25s, border-color .25s;
}
.hm-mid-go::before {
    content: ''; position: absolute; inset: 0; margin: auto;
    width: 8px; height: 8px;
    border-top: 2px solid currentColor; border-right: 2px solid currentColor;
    transform: translateX(-2px) rotate(45deg);
    transition: transform .25s;
}

/* ---- 悬停 / 键盘聚焦态（#167 的 A）----
   两处线索叠在一起，是因为单靠一处都不够明确：
     · 图片推近 3% —— 页面整体的"这块活了"；
     · 箭头按钮填成品牌蓝 + 箭头右移 3px —— 明确指向"点了会走"。
   ⚠ `:focus-visible` 必须和 `:hover` 写在一起：键盘 Tab 到这条横幅时，
     如果只有 hover 有反馈，键盘用户看到的是一个没有任何变化的图片。 */
.hm-mid-link.is-media:hover .hm-mid-img,
.hm-mid-link.is-media:focus-visible .hm-mid-img { transform: scale(1.03); }
.hm-mid-link:hover .hm-mid-go,
.hm-mid-link:focus-visible .hm-mid-go {
    background-color: var(--hs-blue); border-color: var(--hs-blue);
}
.hm-mid-link:hover .hm-mid-go::before,
.hm-mid-link:focus-visible .hm-mid-go::before { transform: translateX(2px) rotate(45deg); }
.hm-mid-link:focus-visible { outline: 3px solid var(--hs-blue); outline-offset: 2px; }


/* ---- 内页横幅（分类页 / 内容栏目页 / 社区页）---- */
.ad-ban {
    position: relative; max-width: var(--hs-container); margin: 0 auto 24px;
    min-height: 120px; background-color: var(--hs-blue-dark); overflow: hidden;
}
.ad-ban-img { display: block; width: 100%; height: auto; }
.ad-ban-inner {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    justify-content: center; padding: 0 40px;
}
.ad-ban-title { font-size: 30px; line-height: 1.3; color: var(--hs-white); margin: 0; text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
.ad-ban-intro { font-size: 16px; line-height: 1.7; color: var(--hs-white); margin: 10px 0 0; text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
/* §136（2026-09-27 JACK）：techforum 页横幅缩到原 .ab-head 体量（191px）——
   仅 include 传 ban_size="sm" 的页面生效（分类页/内容页原样）。
   §137（同日 JACK）：回调到 240px。
   图定高裁切（object-fit cover），深蓝兜底与 .ad-ban 同源。 */
.ad-ban-sm { min-height: 240px; }
.ad-ban-sm .ad-ban-img { height: 240px; object-fit: cover; }

/* ---- 社区右栏广告 ---- */
.ad-side { margin-bottom: 24px; }
.ad-side-link { display: block; }
.ad-side-img { display: block; width: 100%; height: auto; }

/* ---- 社区分享按钮 ---- */
.ad-share { background-color: var(--hs-white); padding: 24px; margin-bottom: 24px; }
.ad-share-title { font-size: 17px; color: var(--hs-text); margin: 0 0 16px; }
.ad-share-list { display: flex; flex-wrap: wrap; gap: 10px; }
.ad-share-link {
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    min-width: 38px; height: 38px; padding: 0 8px;
    border: 1px solid var(--hs-line); transition: border-color .2s ease;
}
.ad-share-link:hover { border-color: var(--hs-blue); }
/* 老站多数分享项本来就没有链接 —— 渲染成不可点的块，而不是点了没反应的 <a href="#"> */
.ad-share-link.is-off { opacity: .5; cursor: default; }
.ad-share-ico { width: 20px; height: 16px; object-fit: contain; }
.ad-share-name { font-size: 12px; color: var(--hs-text-3); white-space: nowrap; }

@media (max-width: 1024px) {
    .hm { --hm-pad: 32px; }
    .hm-hero-slide { min-height: 320px; padding: 52px calc(var(--hm-pad) + var(--hm-gutter)) 44px; }
    .ad-ban-title { font-size: 24px; }
    .ad-ban-inner { padding: 0 32px; }
}

@media (max-width: 768px) {
    .hm-hero-slide { min-height: 260px; padding: 40px calc(var(--hm-pad) + var(--hm-gutter)) 34px; }
    .hm-hero.is-media .hm-title { font-size: 28px; }
    .ad-ban { margin-bottom: 16px; }
    .ad-ban-img { min-height: 110px; object-fit: cover; }
    .ad-ban-title { font-size: 20px; }
    .ad-ban-intro { font-size: 14px; }
    .ad-ban-inner { padding: 0 20px; }
    .ad-share { padding: 18px; }
}

@media (max-width: 480px) {
    .hm-hero.is-media .hm-title { font-size: 24px; }
    .ad-ban-inner { padding: 0 14px; }
}

/* ==========================================================================
   站内搜索 /search
   --------------------------------------------------------------------------
   为什么不复用列表页现成的 .jb-* 卡片：搜索结果是**四种不同密度**的东西
   （品类卡 / 型号行 / 文章卡 / 社区卡）。型号行需要「等宽型号 + 标题」的对齐感，
   卡片做不到；品类卡需要能放型号计数和一句简介。混用会让其中一种变形。
   前缀统一 .se-，与既有选择器无冲突（已 grep 确认无占用）。
   ========================================================================== */
.se-form { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0 14px; max-width: 720px; }
.se-input {
    flex: 1 1 320px; min-width: 0;
    height: 46px; padding: 0 16px;
    border: 1px solid var(--hs-line-3); border-radius: var(--hs-radius);
    font-size: 16px; color: var(--hs-text); background-color: var(--hs-white);
}
.se-input:focus { outline: none; border-color: var(--hs-blue); }
.se-submit {
    flex: 0 0 auto; height: 46px; padding: 0 28px;
    border: 1px solid var(--hs-blue); border-radius: var(--hs-radius);
    background-color: var(--hs-blue); color: var(--hs-white);
    font-size: 16px; font-weight: 700; cursor: pointer;
}
.se-submit:hover { background-color: var(--hs-orange); border-color: var(--hs-orange); }

/* 品类卡 */
.se-cats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.se-cat { border: 1px solid var(--hs-line); transition: border-color .2s ease, box-shadow .2s ease; }
.se-cat:hover { border-color: var(--hs-blue); box-shadow: 0 3px 14px rgba(1, 105, 178, .12); }
.se-cat-link { display: block; padding: 16px 20px; }
.se-cat-name { font-size: 17px; font-weight: 700; color: var(--hs-text); }
.se-cat:hover .se-cat-name { color: var(--hs-blue); }
.se-cat-count {
    display: inline-block; margin-left: 8px; font-size: 12px; color: var(--hs-text-mute);
    background: var(--hs-bg); padding: 0 7px; border-radius: 10px;
}
.se-cat-intro { display: block; margin-top: 6px; font-size: 14px; line-height: 1.7; color: var(--hs-text-3); }

/* 型号行 */
.se-models { display: flex; flex-direction: column; border-top: 1px solid var(--hs-line); }
.se-model { border-bottom: 1px solid var(--hs-line); }
.se-model-link { display: flex; align-items: baseline; gap: 16px; padding: 12px 4px; }
.se-model:hover { background-color: var(--hs-bg); }
.se-model-code {
    flex: 0 0 auto; min-width: 150px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 15px; font-weight: 700; color: var(--hs-blue); word-break: break-all;
}
.se-model-name { flex: 1 1 auto; min-width: 0; font-size: 15px; color: var(--hs-text-2); }
.se-model-sub { flex: 0 0 auto; font-size: 13px; color: var(--hs-text-mute); }

.se-more { margin: 14px 0 0; font-size: 14px; line-height: 1.7; color: var(--hs-text-3); }
.se-more strong { color: var(--hs-text); }

/* 「按品类浏览」复用 .ct-subs 的 flex 布局，但那条自带 40px 侧边距，
   在 .ct-list-wrap（同样自带侧边距）里会变成双份 —— 这里压掉。 */
.se .se-tops { padding: 0; }

@media (max-width: 768px) {
    .se-cats { grid-template-columns: 1fr; }
    .se-model-link { flex-wrap: wrap; gap: 4px 12px; }
    .se-model-code { min-width: 0; }
    .se-model-name { flex: 1 1 100%; }
    .se-submit { padding: 0 20px; }
}

/* ==========================================================================
   设计系统层（2026-09-18 首页样板页一并落地）
   --------------------------------------------------------------------------
   为什么要先建这一层：改造前的 CSS 里这四样**一个都没有**（实测）——
     `--hs-sp-*` 0 · `clamp()` 仅 1 处 · `--hs-ease` 0 · `prefers-reduced-motion` 0 ·
     `position: sticky` 0。
   结果是每个区块各自写 margin（28px / 30px / 32px 混杂），字号在断点处硬跳，
   动效时长随手写，键盘用户和"减少动效"用户完全没被考虑。

   这一层只做加法：**不改任何既有选择器**，新规则只作用于新类名。
   ========================================================================== */

:root {
    /* 间距尺度：4 的倍数，只准用这 8 档 —— 消除"28 还是 30"这类随意值 */
    --hs-sp-1:  4px;
    --hs-sp-2:  8px;
    --hs-sp-3: 12px;
    --hs-sp-4: 16px;
    --hs-sp-5: 24px;
    --hs-sp-6: 32px;
    --hs-sp-7: 48px;
    --hs-sp-8: 64px;

    /* 动效：三档时长 + 一条曲线。曲线两端慢、中段快，比 ease 更像"有质量"的位移 */
    --hs-ease:  cubic-bezier(.2, .7, .3, 1);
    --hs-dur-1: 120ms;
    --hs-dur-2: 200ms;
    --hs-dur-3: 320ms;

    /* 区块标题下沿的分隔线颜色，比 --hs-line 略深，用来切分大区块 */
    --hs-rule:  #e4e9f0;
}

/* ---- 动效降级（无障碍硬要求）----
   改造前全站 0 处。前庭功能受损的用户会因为位移/缩放动画眩晕或头痛，
   系统里已经有现成的用户偏好，跟上即可 —— 不是"动画关掉就没质感了"，
   是把"动不动"这件事的决定权还给用户。 */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   首页区块通用外壳 .hm-sec
   --------------------------------------------------------------------------
   与既有的 .hm-cats / .hm-mid 同一节奏：白底卡片、30px 间隙、40px 内边距。
   新增的 6 个区块全部用它，避免出现第三、第四种间距。
   ========================================================================== */

.hm-sec { background-color: var(--hs-white); padding: var(--hs-sp-7) var(--hm-pad); margin-bottom: 30px; }

/* ★★ 2026-09-20（#214 = C，JACK 原话：「白底＋区块之间有灰色间断细分割线」）
   `.hm` 铺了整片白底之后（见上面 1007 行），区块之间**只剩留白、没有任何边界信号** ⇒
   在白底区块之间补一条 1px 细线，让"到哪里是另一块了"看得出来。

   ★ 「**间断**」的含义 = 线**不贯通到屏幕边**，只画在内容列的宽度内，与卡片列左右缘齐。
     这是它与「退回灰缝」（#214 B，整块背景换色）的本质区别：灰缝是**背景**换色、必然通栏；
     这条线是**内容宽度**上的装饰，左右各留一段白。
   ★ 用**相邻兄弟选择器**，不给每个 `.hm-sec` 加类 —— 这样"哪些位置该有线"是一句写得出来的话：
     · `.hm-cats + .hm-sec`   产品分类 → 推荐产品
     · `.hm-sec + .hm-sec`    推荐产品 → 技术服务 → 资料与认证、技术社区 → 公司简介
     · **故意不写** `.hm-mid + .hm-sec` —— 技术社区上面是**蓝色横幅图**，本身已有强边界，
       再加一条线会让横幅像被框住；也不给 `.hm-ai`（AI 入口条）上下加 ——
       它自己是带边框的盒子，上下再有线会显密。
   ⚠ `pointer-events: none`：装饰层不能挡住它下面（上一块的下外边距区）的点击目标。

   ★★ 为什么把线挂在 **`.hm-inner`** 上、而不是挂在区块本身（第一版就是挂在区块上的，
      被新写的契约 F 当场抓住 —— 这是一次**真缺陷**、不是探针误报）：
      在 **≥1619 档**，`.hm-inner` 带 `max-width: 1440px; margin: 0 auto` ⇒ 它比区块的内容区
      **更窄且水平居中**（1680 档实测：区块内容区 `[70..1595]`、`.hm-inner` `[112.5..1552.5]`）。
      第一版把 `::before` 挂区块、左右写 `var(--hm-pad)` ⇒ 线宽 = 区块内容区宽，
      在宽屏上比卡片列**两边各凸出 42.5px**（1619 档凸 12px）—— 正好是它要避免的那件事。
      挂到 `.hm-inner` 上，线宽**天生**= 内容列宽，宽屏居中、窄屏撑满，全档自洽；
      而且让位档（区块 `padding-right` 收 12px）**也会自动跟着收**，不需要再补一条修正规则。
   ⚠ `.hm-inner` 加 `position: relative` 之前已确认：`.hm-cats` / `.hm-sec` 的这个 `.hm-inner`
     内部**没有任何绝对定位元素**（里面的类全是 grid / flex 布局）⇒ 不改变任何元素的包含块。 */
.hm-cats + .hm-sec > .hm-inner,
.hm-sec + .hm-sec > .hm-inner { position: relative; }
.hm-cats + .hm-sec > .hm-inner::before,
.hm-sec + .hm-sec > .hm-inner::before {
    content: ''; position: absolute; display: block; pointer-events: none;
    left: 0; right: 0;
    height: 1px; background-color: var(--hs-line-3);
}
/* ★ 纵向位置 = 两块之间留白的**正中**，从 `.hm-inner` 顶（= 本区块内容顶）往上量：
     通用式：距本区块外框顶 = (本区块 padding-top − 上一块 padding-bottom − 上一块 margin-bottom) / 2
     · `.hm-cats` **没有下外边距** ⇒ 距外框顶 0     ⇒ 距内容顶 = **−(--hs-sp-7)**
     · `.hm-sec`  有 30px 下外边距  ⇒ 距外框顶 −15px ⇒ 距内容顶 = **−(--hs-sp-7) − 15px**
   ⚠ 若将来改了 `.hm-sec` 的 `margin-bottom`（30px）或 `--hs-sp-7`，这两个偏移必须一起重算。 */
.hm-cats + .hm-sec > .hm-inner::before { top: calc(-1 * var(--hs-sp-7)); }
.hm-sec + .hm-sec > .hm-inner::before { top: calc(-1 * var(--hs-sp-7) - 15px); }

/* ---- 区块头：标题 + 说明 + 右侧「查看全部」----
   ★★ 2026-09-19：这里原来有一个 `.hm-kicker`（12px 大写英文小标签），
   与它下面的 h2 语义两两重复（Featured / Featured products、
   Downloads / Resources & compliance、Services / Engineering services、
   Tech Forum / Tech forum、About / About Hypersemi）——JACK 定「保留一份」，
   小标签整条删除（模板里的 5 处已同步删净，CSS 规则也不再保留）。
   原来是给欧美半导体站（TI / Infineon）的通行写法，但中文站上会白白多一行英文。

   ⚠ 间距为什么会变成 52px（实测值）：
     h2 自带 margin-bottom，同时 .hm-sec-head 也有 margin-bottom，
     而 .hm-sec-head-txt 是**弹性项目**（父级 display:flex）——
     弹性项目的子元素外边距**不会**像普通块那样与父级塌陷，
     h2 的 26px 就原样留在了父级盒里，与头部的 26px 相加。
     实测：产品分类 26px、推荐产品/资料与认证 52px（双倍）。
   现在把「区块头 → 正文」的间距**只留给 .hm-sec-head 一个来源**，
   头内部的 h2 / 副标题一律归零，任何区块都是同一个 24px。 */
.hm-sec-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--hs-sp-5); margin-bottom: var(--hs-sp-5);
}
.hm-sec-head-txt { min-width: 0; }
.hm-sec-head .hm-h2 { margin-bottom: 0; }
.hm-sec-head .hm-sec-sub { margin-top: var(--hs-sp-3); margin-bottom: 0; }
.hm-sec-sub {
    margin: 0 0 var(--hs-sp-5); max-width: 760px;
    font-size: 15px; line-height: 1.75; color: var(--hs-text-3);
}
.hm-sec-more {
    flex: 0 0 auto; font-size: 15px; font-weight: 700; color: var(--hs-blue);
    padding-bottom: 2px; border-bottom: 1px solid transparent;
    transition: border-color var(--hs-dur-2) var(--hs-ease);
}
.hm-sec-more:hover { border-bottom-color: var(--hs-blue); }

/* ==========================================================================
   Hero 内嵌 4 CTA
   --------------------------------------------------------------------------
   4 个 CTA 放在 track 之外的**绝对定位条**上，不是每张 slide 各放一份：
   3 张图就会有 3 份重复导航，屏幕阅读器还会把同一组链接念三遍。
   ========================================================================== */

.hm-hero.is-media { position: relative; }
.hm-hero.is-media .hm-hero-slide { padding-bottom: 148px; }   /* 给 CTA 条留位 */

.hm-hero-cta {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    padding: 0 calc(var(--hm-pad) + var(--hm-gutter)) var(--hs-sp-5);
    /* 自下而上的压暗渐变：运营换一张浅色图时 CTA 文字仍然可读，
       不依赖图片本身的亮度 —— 这条与广告位那段的注释是同一个考虑。 */
    background-image: linear-gradient(to top, rgba(0, 0, 0, .62), rgba(0, 0, 0, 0));
}
.hm-hero-cta .hm-inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--hs-sp-5); flex-wrap: wrap;
}

.hm-cta-list { display: flex; flex-wrap: wrap; gap: var(--hs-sp-2); }
.hm-cta-item { display: flex; }
.hm-cta-link {
    display: inline-flex; align-items: center; gap: var(--hs-sp-2);
    min-height: 44px;                     /* 触控目标 ≥44px，移动端硬要求 */
    padding: 0 var(--hs-sp-5);
    border: 1px solid rgba(255, 255, 255, .55); border-radius: var(--hs-radius);
    background-color: rgba(1, 105, 178, .38);
    color: var(--hs-white); font-size: 15px; font-weight: 700;
    transition: background-color var(--hs-dur-2) var(--hs-ease),
                border-color var(--hs-dur-2) var(--hs-ease),
                color var(--hs-dur-2) var(--hs-ease);
}
.hm-cta-link:hover {
    background-color: var(--hs-orange); border-color: var(--hs-orange); color: var(--hs-white);
}
/* 第一个是主行动，实心橙；其余描边 —— 一屏里只强调一件事 */
.hm-cta-item:first-child .hm-cta-link {
    background-color: var(--hs-orange); border-color: var(--hs-orange);
}
.hm-cta-item:first-child .hm-cta-link:hover { background-color: var(--hs-orange-dark); border-color: var(--hs-orange-dark); }
.hm-cta-arrow { transition: transform var(--hs-dur-2) var(--hs-ease); }
.hm-cta-link:hover .hm-cta-arrow { transform: translateX(3px); }

/* 无素材的纯文本 hero：CTA 落在白底上，配色要反过来，但按钮形态保持一致 */
.hm-hero:not(.is-media) .hm-cta { margin-top: var(--hs-sp-5); }
.hm-hero:not(.is-media) .hm-cta-link {
    border-color: var(--hs-line-3); background-color: var(--hs-white); color: var(--hs-blue);
}
.hm-hero:not(.is-media) .hm-cta-link:hover {
    border-color: var(--hs-orange); background-color: var(--hs-orange); color: var(--hs-white);
}
.hm-hero:not(.is-media) .hm-cta-item:first-child .hm-cta-link {
    background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white);
}
.hm-hero:not(.is-media) .hm-cta-item:first-child .hm-cta-link:hover {
    background-color: var(--hs-orange); border-color: var(--hs-orange);
}
/* 纯文本 hero 里的 hm-stat 原本 margin:0，与 CTA 贴太近 */
.hm-hero:not(.is-media) .hm-stat { margin-bottom: var(--hs-sp-1); }

/* ==========================================================================
   ⑦ 技术社区（替代老站「应用领域」）
   ========================================================================== */

/* 融合区块（技术社区）里的小节标题 —— 2026-09-19 JACK 指令把「形态入口」和
   「文章精选」合成一个 section，用一个 h3 把两层内容分开：
   h2 技术社区 → 形态卡 → h3 最新文章 → 文章卡。
   上面那条 border-top + 大上边距，是它区别于区块标题的全部手段（不再另起 section）。 */
.hm-forum-sub {
    margin: var(--hs-sp-6) 0 var(--hs-sp-4);
    padding-top: var(--hs-sp-5);
    border-top: 1px solid var(--hs-line);
    font-size: 20px; font-weight: 700; color: var(--hs-text);
}
.hm-shapes { display: flex; flex-wrap: wrap; align-items: stretch; --gw: var(--hs-sp-3); gap: var(--gw); }
.hm-shape { border: 1px solid var(--hs-line); border-left: 3px solid var(--hs-blue); }
.hm-shape-link {
    display: block; height: 100%; padding: 18px 20px;
    transition: background-color var(--hs-dur-2) var(--hs-ease);
}
.hm-shape-link:hover { background-color: var(--hs-blue-light); }
.hm-shape-name { display: block; font-size: 17px; font-weight: 700; color: var(--hs-text); }
.hm-shape-link:hover .hm-shape-name { color: var(--hs-blue); }
.hm-shape-count {
    display: inline-block; margin-top: var(--hs-sp-2);
    font-size: 12px; color: var(--hs-text-mute);
    background-color: var(--hs-bg); padding: 1px 9px; border-radius: 10px;
    font-variant-numeric: tabular-nums;
}
.hm-shape-intro { display: block; margin-top: var(--hs-sp-2); font-size: 14px; line-height: 1.7; color: var(--hs-text-3); }

/* ==========================================================================
   ⑧ 服务四项
   ========================================================================== */

/* 服务卡 4→3（2026-09-25 JACK）：数据源已切 hs_service_section 三项（定制/失效分析/晶圆加工），
   4 栏网格会留一个空格 ⇒ 改 3 栏。服务项白名单在 Repo::PAGES 固定 3 个，列数与数据天然一致。 */
.hm-svc-grid { display: flex; flex-wrap: wrap; align-items: stretch; --gw: 18px; gap: var(--gw); }
.hm-svc-card {
    border: 1px solid var(--hs-line); border-top: 3px solid var(--hs-blue);
    transition: box-shadow var(--hs-dur-2) var(--hs-ease);
}
.hm-svc-card:hover { box-shadow: 0 4px 16px rgba(1, 105, 178, .14); }
.hm-svc-link { display: flex; flex-direction: column; height: 100%; padding: 22px; }
.hm-svc-name { display: block; font-size: 18px; font-weight: 700; color: var(--hs-text); }
.hm-svc-card:hover .hm-svc-name { color: var(--hs-blue); }
.hm-svc-intro { display: block; flex: 1 1 auto; margin-top: var(--hs-sp-3); font-size: 14.5px; line-height: 1.75; color: var(--hs-text-2); }
/* ⚠ .hm-svc-count（原「N posts」徽章）已随 #138 一并删除：
   本区块列的是技术服务、不是文章，徽章语义错位，英文站还会出现「1 posts」单复数错。
   若将来要恢复，记得用单复数分支（count == 1 时用 post）。 */

/* ==========================================================================
   ⑨ 资料与认证
   ========================================================================== */

.hm-dl-grid { display: flex; flex-wrap: wrap; align-items: stretch; --gw: 18px; gap: var(--gw); }
.hm-dl-card { border: 1px solid var(--hs-line); background-color: var(--hs-bg); }
.hm-dl-link {
    display: block; height: 100%; padding: 22px;
    transition: background-color var(--hs-dur-2) var(--hs-ease);
}
.hm-dl-link:hover { background-color: var(--hs-white); }
.hm-dl-name { display: block; font-size: 18px; font-weight: 700; color: var(--hs-text); }
.hm-dl-link:hover .hm-dl-name { color: var(--hs-blue); }
.hm-dl-intro { display: block; margin-top: var(--hs-sp-3); font-size: 14.5px; line-height: 1.75; color: var(--hs-text-2); }

/* ==========================================================================
   ⑩ 技术文章精选
   ========================================================================== */

.hm-post-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.hm-post-card {
    border: 1px solid var(--hs-line);
    transition: box-shadow var(--hs-dur-2) var(--hs-ease);
}
.hm-post-card:hover { box-shadow: 0 4px 16px rgba(1, 105, 178, .14); }
.hm-post-link { display: flex; flex-direction: column; height: 100%; }
/* ⚠ aspect-ratio 必须配 max-height 一起用。
   它算的是「容器宽度 × 比例」——列数一少、容器一宽，媒体区就跟着拔高：
   实测 768px 断点单列时 .hm-post-media 变成 688×387、.hm-feat-media 变成 688×492，
   整块区域被一张缩略图撑成几百像素的空白。宽度只该决定「图有多宽」，
   不该决定「这块留多高」。 */
.hm-post-media { display: block; aspect-ratio: 16 / 9; max-height: 220px; overflow: hidden; background-color: var(--hs-bg); }
.hm-post-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hm-post-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 18px 20px 20px; }
.hm-post-title {
    display: block; font-size: 16.5px; font-weight: 700; line-height: 1.5; color: var(--hs-text);
    /* 长标题最多两行 —— 三行以上会把同一行的相邻卡片撑出不同高度 */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.hm-post-card:hover .hm-post-title { color: var(--hs-blue); }
.hm-post-intro {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
    margin-top: var(--hs-sp-2); font-size: 14px; line-height: 1.7; color: var(--hs-text-3);
}
.hm-post-meta {
    display: flex; flex-wrap: wrap; gap: var(--hs-sp-4);
    margin-top: auto; padding-top: var(--hs-sp-3);
    font-size: 12.5px; color: var(--hs-text-mute); font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   ⑪ 推荐产品
   --------------------------------------------------------------------------
   型号用等宽字体 + 首字母大写保留：型号是工程师唯一精确匹配的东西，
   等宽能让 `SMBJ6.0A` / `SMBJ6.0CA` 这种只差两个字符的型号一眼分辨。
   ========================================================================== */

.hm-feat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.hm-feat-card { border: 1px solid var(--hs-line); transition: box-shadow var(--hs-dur-2) var(--hs-ease); }
.hm-feat-card:hover { box-shadow: 0 4px 16px rgba(1, 105, 178, .14); }
.hm-feat-link { display: flex; flex-direction: column; height: 100%; padding: 16px; }
/* ★★ 2026-09-19 JACK 指令：产品图「不使用背景」+「减少空白空间」。
   三处一起改才成立，少一处就还是空：
     ① 去掉 background-color —— 原先是 var(--hs-bg) 的灰底色块。
        实测 8 张主图里 6 张本身是 **RGBA 透明背景**（alpha 0~255），
        灰底色块会把它们的透明区染成灰色，看着像"图没加载出来"；
        另 2 张（M34.png 是 P 模式无 alpha、TO-220F.png 的 alpha 恒为 255）
        是白底图，卡片本身白底 ⇒ 去掉灰底后它们同样无缝。⇒ 6 张变干净、2 张不受影响。
     ② aspect-ratio 4/3 → 1/1 —— 这是"空白"的主因：
        8 张里 7 张是 1:1 的方图（340×340 / 300×300 / 640×640），
        塞进 4:3 的框里用 contain 装填，会被**高度**卡住，
        图片只能占到框宽的 75%，左右各空 12.5%。
        改成 1:1 恰好贴合真实比例，图能占满框宽。
     ③ 图片装填 88% → 100% —— 方图在方框里满铺，画布内的自带留白（实测内容
        只占画布 40%~77%）已经是唯一剩余空白，不再由 CSS 额外加一圈。
   ⚠ max-height 必须保留：单列（≤560）时卡片宽 520px，1:1 会把媒体区拔到 520px 高
     （同 .hm-feat-media / .hm-post-media 上方关于 aspect-ratio 的说明）。
     240px 是四档下的共同上限：@1440 框宽 280 ⇒ 触发，@1024 256 ⇒ 触发，
     @768 291 ⇒ 触发，@390 290 ⇒ 触发；四档高度一致，卡片不会忽高忽低。
   ⚠ 副作用（已实测）：媒体区由 4/3 的 210px 高变成 240px，每张卡高 +30px。
   ------------------------------------------------------------------------- */
.hm-feat-media {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 1 / 1; max-height: 240px;
    overflow: hidden;
    margin-bottom: var(--hs-sp-3);
}
.hm-feat-media.is-plain { aspect-ratio: auto; min-height: 96px; }   /* 无图时不撑 1:1 的大空块 */
.hm-feat-img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
/* 图下方的**二级类别名**（原来放型号）。
   居中、允许折行（英文类别名如 High Voltage MOSFETs (650V+) 在窄卡里会换行，
   所以不用 nowrap + 省略号 —— 那会把名字静默截断，而「更多」提示已随型号一起删掉）。
   margin-top: auto 把这一行压到卡片底部，中英卡片、有图无图卡片的文字基线都一致。 */
.hm-feat-line {
    display: block; margin-top: auto; padding-top: var(--hs-sp-3);
    text-align: center; font-size: 15px; font-weight: 700; line-height: 1.4;
    color: var(--hs-blue); overflow-wrap: break-word;
}

/* ==========================================================================
   ⑫ 关于我们
   ========================================================================== */

/* 两态网格：
     · 无形象图 → 文字 | 统计（1.7fr 1fr，与改造前完全一致，不会塌）
     · 有形象图 → 图 | 文字+统计（图占左栏跨两行）
   ⚠ 用 grid-template-areas 而不是靠 DOM 顺序 —— 有图时是 3 个子项（图/文/统计），
     自动排布会把统计甩到第二行第一列（图的下面），而不是文字的下方。 */
.hm-about-grid {
    display: grid; gap: 40px; align-items: center;
    grid-template-columns: 1.7fr 1fr;
    grid-template-areas: "txt stats";
}
.hm-about-txt { grid-area: txt; min-width: 0; }
.hm-about-stats { grid-area: stats; }

.hm-about-grid.is-media {
    grid-template-columns: 4fr 8fr;
    grid-template-areas: "figure txt" "figure stats";
    gap: var(--hs-sp-5) var(--hs-sp-7);
    align-items: start;
}
/* ★ aspect-ratio 必配 max-height。
   只写比例时高度 = 容器宽 × 比例，窄列会被拉得过高（本项目已栽过一次：
   精选产品媒体区单列时被撑到 492px）。这里 4:3 配 380px 上限，
   桌面 4fr 列宽 417px → 自然高 313px，上限不生效；极端窄列时兜住。 */
.hm-about-figure {
    grid-area: figure; margin: 0; overflow: hidden;
    aspect-ratio: 4 / 3; max-height: 380px;
    border-radius: var(--hs-radius); background-color: var(--hs-bg);
}
.hm-about-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* is-media 时统计在文字列**下方**，所以是上边框不是左边框 */
.hm-about-grid.is-media .hm-about-stats {
    padding-left: 0; border-left: 0;
    padding-top: var(--hs-sp-4); border-top: 1px solid var(--hs-rule);
}
.hm-about-intro { margin: var(--hs-sp-4) 0 0; max-width: 760px; font-size: 15.5px; line-height: 1.85; color: var(--hs-text-2); }
.hm-about-more {
    display: inline-block; margin-top: var(--hs-sp-4);
    font-size: 15px; font-weight: 700; color: var(--hs-blue);
    border-bottom: 1px solid transparent; transition: border-color var(--hs-dur-2) var(--hs-ease);
}
.hm-about-more:hover { border-bottom-color: var(--hs-blue); }
.hm-about-stats {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--hs-sp-4);
    padding-left: 40px; border-left: 1px solid var(--hs-rule);
}
.hm-about-stats li { text-align: center; }
.hm-about-stats strong {
    display: block; font-size: 30px; font-weight: 700; line-height: 1.15;
    color: var(--hs-blue); font-variant-numeric: tabular-nums;
}
.hm-about-stats span { display: block; margin-top: var(--hs-sp-1); font-size: 13px; color: var(--hs-text-3); }

/* ==========================================================================
   右侧悬浮工具条（老站右侧栏 → 新站全站接线）
   --------------------------------------------------------------------------
   桌面：贴右边缘的竖条，常驻。
   手机/平板（≤1024px）：**改成底部固定条**，不是隐藏 —— 右侧竖条在窄屏会盖住
   正文，但询盘入口不能丢，所以换位置而不是砍掉。纯 CSS，HTML 一份。
   ========================================================================== */

/* ★ 2026-09-20（台账 #207 = A「两边各让一点」）：右边距 12 → 4px。
   首页最右一列卡片的**右边框**落在「视口 − 70」上（`.hm` 留白 30 + `.hm-sec` 内边距
   40），而这条竖条原来从「视口 − 76」开始 —— 正好压掉 6px 边框（JACK 的截图里
   看得很清楚：第 4 列卡片的右边框在挂件那一段断掉了）。
   整条右移 8px 后左缘到「视口 − 68」，再配合文件末尾给白底块加的 12px 右内边距，
   卡片右缘到「视口 − 82」⇒ **净空 14px**，边框完整露出来。完整推导见文件末尾。 */
.sd { position: fixed; right: 4px; top: 50%; transform: translateY(-50%); z-index: 60; }
.sd-list { display: flex; flex-direction: column; gap: var(--hs-sp-1); }
.sd-item { position: relative; }
.sd-link {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; width: 64px; padding: 9px 4px;
    background-color: var(--hs-white); border: 1px solid var(--hs-line);
    color: var(--hs-text-2); font-size: 12px; line-height: 1.2;
    transition: background-color var(--hs-dur-2) var(--hs-ease),
                border-color var(--hs-dur-2) var(--hs-ease),
                color var(--hs-dur-2) var(--hs-ease);
}
.sd-link:hover { background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white); }
.sd-link:hover .sd-ico { filter: brightness(0) invert(1); }
.sd-link.is-off { cursor: default; color: var(--hs-text-mute); }
.sd-link.is-off:hover { background-color: var(--hs-white); border-color: var(--hs-line); color: var(--hs-text-mute); }
.sd-link.is-off:hover .sd-ico { filter: none; }
.sd-ico { width: 26px; height: 20px; object-fit: contain; }
.sd-label { white-space: nowrap; }

/* 悬停提示：把 title 里的详细信息（电话号 / 邮箱）露出来，不占常驻空间 */
.sd-tip {
    position: absolute; right: calc(100% + 8px); top: 50%; transform: translateY(-50%);
    padding: 6px 10px; background-color: rgba(0, 0, 0, .84); color: var(--hs-white);
    font-size: 13px; white-space: nowrap; opacity: 0; pointer-events: none;
    transition: opacity var(--hs-dur-2) var(--hs-ease);
}
.sd-item:hover .sd-tip { opacity: 1; }

/* 回顶部：默认不显示，main.js 滚过 400px 后加 .is-on。
   ⇒ 没有 JS 时它永远不出现，也就不会有一个"点了没反应"的按钮。 */
.sd-top {
    /* ★ 2026-09-20（#207 = A）：12 → 4px，与上面 `.sd` 的右缘对齐 ——
       同一个右边缘上的两个挂件错开 8px，看着像没对齐的 bug。 */
    position: fixed; right: 4px; bottom: 20px; z-index: 61;
    display: none; flex-direction: column; align-items: center; gap: 3px;
    width: 64px; padding: 9px 4px;
    background-color: var(--hs-white); border: 1px solid var(--hs-line);
    color: var(--hs-text-2); font-size: 12px;
}
.sd-top.is-on { display: flex; }
.sd-top:hover { background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white); }
.sd-arrow {
    width: 10px; height: 10px; margin-top: 3px;
    border-left: 2px solid currentColor; border-top: 2px solid currentColor;
    transform: rotate(45deg);
}

/* ---- 响应式：≤1200 收窄竖条；≤1024 换底部条 ---- */
@media (max-width: 1200px) {
    /* ⚠ 这一档**不降列数**。
       1200px 视口的容器还有 1140px，4 列每列 272px —— 产品卡完全放得下。
       原来在这里把 svc/feat 降到 3 列，是多余的一档，只是把首页拉长。 */
    /* ★ 公司简介在「有形象图」时也要回到单列（否则 3 个子项挤 2 列）。
       grid-template-areas 必须一起清掉 —— 只写 1fr 会让 "figure txt" 这种
       两列模板与单列冲突，靠后的声明获胜，结果是图和文字并排挤在 1fr 里。
       清掉后按 DOM 顺序（图 → 文 → 统计）自动堆叠。 */
    .hm-about-grid,
    .hm-about-grid.is-media {
        grid-template-columns: 1fr; grid-template-areas: none;
        gap: var(--hs-sp-6); align-items: start;
    }
    .hm-about-figure, .hm-about-txt, .hm-about-stats { grid-area: auto; }
    /* 单列时如果图占满 1140px 容器，4:3 会拉到 855px 高 —— 限个宽度更像「配图」 */
    .hm-about-figure { max-width: 560px; }
    .hm-about-stats { padding-left: 0; border-left: 0; padding-top: var(--hs-sp-5); border-top: 1px solid var(--hs-rule); }
    .hm-about-grid.is-media .hm-about-stats { padding-top: var(--hs-sp-5); }
}

@media (max-width: 1024px) {
    .hm-sec { padding: var(--hs-sp-6) var(--hm-pad); }
    /* ⚠ 产品分类（.hm-cats）必须跟着 .hm-sec 一起改。
       它的左右内边距一旦与 .hm-sec 不同，两块的 .hm-inner 宽度就不等
       （实测 884 vs 900），标题字号一提就会看出左右错位。
       竖向内边距也一并对齐（原来是裸的 40px，与 .hm-sec 的 32px 不等）。 */
    .hm-cats { padding: var(--hs-sp-6) var(--hm-pad); }
    /* 1024px 视口的容器有 964px，这一档**只把产品卡降到 3 列**：
         feat 3 列 = 308px、shapes 3 列 = 308px、post 3 列 = 308px、svc 4 列 = 241px
       其余全放得下，无需降列。
       原来是 svc/feat/shapes/post 一起降到 2 列，把首页多拉了 400~700px。
       完整列数规则见文件末尾「紧凑断点」上方的表。 */
    .hm-feat-grid { grid-template-columns: repeat(3, 1fr); }

    /* 悬浮竖条 → 底部固定条 */
    body { padding-bottom: 58px; }
    .sd {
        right: 0; left: 0; top: auto; bottom: 0; transform: none;
        background-color: var(--hs-white); border-top: 1px solid var(--hs-line);
    }
    .sd-list { flex-direction: row; justify-content: space-around; gap: 0; }
    .sd-item { flex: 1 1 0; min-width: 0; }
    .sd-link {
        width: 100%; min-height: 56px; padding: 6px 2px;
        border: 0; border-right: 1px solid var(--hs-line); font-size: 11px;
    }
    .sd-item:last-child .sd-link { border-right: 0; }
    .sd-ico { width: 22px; height: 17px; }
    .sd-tip { display: none; }
    /* 底部条上放回顶部没有意义，隐藏以免占掉一个位置 */
    .sd-top { display: none !important; }
}

@media (max-width: 768px) {
    .hm-sec { padding: var(--hs-sp-5) var(--hm-pad); margin-bottom: 16px; }
    /* ★ .hm-cats 的每一档都必须与 .hm-sec 写在同一块里（见 1721 行附近的说明）：
       窄屏下 @1024 / @768 / @480 会层层命中，谁的规则在文件里靠后谁赢。
       按 基础 → @1024 → @768 → @480 的顺序摆放，才能得到预期的 40 / 32 / 20 / 14。 */
    .hm-cats { padding: var(--hs-sp-5) var(--hm-pad); }
    /* margin-bottom 不再单独写：与基线一致用 var(--hs-sp-5)，
       这样「区块头 → 正文」在 1440 / 1024 / 768 / 390 四档都是同一个 24px。 */
    .hm-sec-head { flex-direction: column; align-items: flex-start; gap: var(--hs-sp-3); }
    .hm-sec-sub { font-size: 14px; }
    .hm-h2 { font-size: 22px; }

    .hm-hero.is-media .hm-hero-slide { padding-bottom: 184px; }   /* CTA 换行成 2 行 */
    .hm-hero-cta { padding: 0 calc(var(--hm-pad) + var(--hm-gutter)) var(--hs-sp-4); }
    .hm-hero-cta .hm-inner { flex-direction: column; align-items: stretch; gap: var(--hs-sp-3); }
    .hm-cta-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--hs-sp-2); }
    .hm-cta-item { min-width: 0; }
    .hm-cta-link { justify-content: space-between; padding: 0 var(--hs-sp-4); font-size: 14px; }

    /* ⚠ 这里**不再**一刀切成单列。
       768px 是「平板竖屏 / 小笔记本窗口」，容器宽约 728px —— 两列每列 355px，
       卡片完全放得下。原来全部改成 1fr 的结果是：推荐产品 8 条堆成 5,109px、
       产品分类 32 项堆成 1,286px，整个首页被拉到 12,576px，**比 390px 手机版还长**。
       真正的单列是手机（≤560），在下面的“紧凑断点”里统一处理。
       列数规则表见同处。 */
    .hm-post-grid, .hm-feat-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    /* #374：自适应栅格（hm-grid/hm-shapes/hm-svc-grid）在平板统一压 2 列 ——
       后台改成任意数量都不会破版；宽度类的 .wK 被 0,2,0 同特异度靠后规则覆盖。 */
    .hm-grid.hm-adapt > li, .hm-shapes.hm-adapt > li, .hm-svc-grid.hm-adapt > li {
        width: calc((100% - var(--gw)) / 2);
    }
    .hm-about-stats { grid-template-columns: repeat(3, 1fr); gap: var(--hs-sp-2); }
    .hm-about-stats strong { font-size: 24px; }

    /* 中部横幅叠字降一档（#167 配套，理由见下方 ≤560 的注释）：
       容器 728 ⇒ 图高 = 728 ÷ 7.11 ≈ 102px，19px 字在这上面显得占满整条。 */
    .hm-mid-link.is-media .hm-mid-text { padding: 18px 22px 12px; font-size: 15px; gap: 10px; }
    .hm-mid-go { width: 34px; height: 34px; }
}

/* ==========================================================================
   紧凑断点：≤560 —— 这才是「一列」该出现的地方

   ── 首页网格列数规则（按**容器可用宽度**定，不是按屏幕宽度拍）─────────────
    容器宽      来源断点    网格          列数    单列宽   依据
    ─────────────────────────────────────────────────────────────────────
    1380       base        全部           基准
    1140       ≤1200       （不降列）      —      272+   放得下就别降，降只拉长
     964       ≤1024       feat 3 列            308    其余保持基准
     728       ≤768        全部 2 列            355
     520       ≤560        全部 1 列            520    两列只剩 244px，型号被拦腰断
    ─────────────────────────────────────────────────────────────────────
   基准（#374 起 hm-grid/hm-shapes/hm-svc-grid/hm-dl-grid 为 flex 自适应栅格，
         列数由控制器按卡片数量算：<4 一行 / 偶数两行等分 / 奇数上少下多）：
         当前数据渲染效果 = .hm-grid 4 / .hm-shapes 3 / .hm-svc-grid 3 / .hm-dl-grid 3
         .hm-post-grid 3 / .hm-feat-grid 4（这两个仍是固定 grid）

   为什么单独开 560 而不是继续用 768：
     768 与 390 之间差了近一倍宽度（容器 728 vs 350），
     两者共用一个断点必然有一头是错的。之前错的是 768 这头。
   560 的依据：容器 ≈ 520px，两列每列 244px —— 型号 `SMBJ6.0CA` 加一行参数
   已经挤到换行两三次，再分列就没有可读性了，此时改单列才对。
   ========================================================================== */
@media (max-width: 560px) {
    /* 标题再降一档：390 视口下 hero 的 H1 是 24px（见 .hm-hero.is-media .hm-title），
       h2 若停在 22px，两者只差 2px，标题层级会糊成一片。 */
    .hm-h2 { font-size: 20px; }
    .hm-post-grid, .hm-feat-grid {
        grid-template-columns: 1fr;
    }
    /* #374：自适应栅格手机全单列（含 dl-grid —— 它在 768 档保持 3 列，这里才落单列） */
    .hm-grid.hm-adapt > li, .hm-shapes.hm-adapt > li, .hm-svc-grid.hm-adapt > li, .hm-dl-grid.hm-adapt > li {
        width: 100%;
    }
    /* 单列时卡片很宽，媒体区靠 max-height 兜住（见 .hm-feat-media 注释） */
    .hm-post-media { max-height: 190px; }

    /* ---- 中部横幅：手机上放弃叠字，回到「图在上、深色条在下」（#167 配套）----
       ★ 为什么这一档必须整个退回，而不是像 768 那样只降字号：
         这条横幅是**通栏 + aspect-ratio 1600/225** ⇒ 高度 = 容器宽 ÷ 7.11，
         **屏幕越窄，图越扁**（和普通卡片正好相反）。实测各档图高：
             1440 → 容器 1380 → 图高 194px   叠字 19px 只用到 22%，像广告位
              768 → 容器  728 → 图高 102px   降到 15px，还能看
              560 → 容器  520 → 图高  73px   字 + 上下内边距要 70px+，等于把图糊掉
              390 → 容器  350 → 图高  49px   图上放一个字都放不下
         ⇒ 从 560 起改成静态条，位置关系回到改之前（图在上、字在下），
           但**保留右侧箭头与悬停态** —— 它是"还能点"的那条线索，不能一起丢。
       ⚠ 只用 position:static 覆盖，**不许 display:none**：文字是这条广告的正文，
         藏起来就等于这条广告变成一张没有任何信息的图。
       ⚠ 渐变底也必须一并撤掉（position 变静态后它会变成文字背后的一块深色方块），
         改用与 ::not(.is-media) 兜底同色的实心 --hs-blue-dark。 */
    .hm-mid-link.is-media .hm-mid-text {
        position: static; padding: 14px 16px; font-size: 14.5px; gap: 10px;
        background-image: none; background-color: var(--hs-blue-dark);
        text-shadow: none;
    }
    .hm-mid-go { width: 30px; height: 30px; }
    .hm-mid-go::before { width: 7px; height: 7px; border-width: 2px; }
}

@media (max-width: 480px) {
    .hm { --hm-pad: 14px; }
    .hm-sec { padding: var(--hs-sp-5) var(--hm-pad); }
    .hm-cats { padding: var(--hs-sp-5) var(--hm-pad); }
    .hm-cta-link { min-height: 42px; font-size: 13.5px; }
    .hm-shape-link, .hm-svc-link, .hm-dl-link { padding: 18px 16px; }
    .hm-about-stats strong { font-size: 21px; }
}

/* ==========================================================================
   中部横幅的箭头 × 右侧固定工具条（台账 #167 配套，2026-09-19 实测发现）
   --------------------------------------------------------------------------
   #167 把中部横幅改成「图上叠字 + 右侧箭头」之后，箭头落在横幅**最右侧**，
   正好撞上 `position:fixed` 的右侧工具条 `.sd`。

   量出来的情况（`analysis/_overlap_probe.js`，A=.sd / B=.hm-mid-go）：
       1025 / 1200 / 1440 / 1500  →  X 重叠 **恒为 +12px**
       1591                       →  已错开（-33px）
   ⇒ 也就是说在 **1025 ~ 1591px** 这一段，工具条会切掉箭头右边 12px（40px 的圆里切掉 12px）。

   ⚠ 为什么只在这一段处理，两个边界都不是估的：
     · **≤1024** —— main.css:2531 起 `.sd` 变成屏幕底部横条（`body{padding-bottom:58px}`），
       不再占右侧，也就不可能横向压到任何东西；
     · **≥1591** —— 实测已错开。这一段连"要不要修"都不用判断。
   ⚠ 这不推翻 #106（JACK 已定：正文被工具条压住按现状接受）。
     区别在于：正文被压是**文字**，#106 权衡过可以忍；而箭头是 #167 新加的**可点控件**，
     被切掉一角会让人以为按钮坏了 ⇒ 只把新控件挪开，其余一切照旧。

   ★ 做法只有一件事：把叠字层的**右内边距**加大到 52px，把箭头往里推 18px
     （34 → 52，比所需的 12px 多留 6px 余量）。字号、上下内边距、图片一律不动。
   ⚠ 必须写在文件**最后**：这几档 media 的选择器完全相同
     （`.hm-mid-link.is-media .hm-mid-text`），后出现的才赢。
     若放在 ≤560 之前，那条 `padding: 14px 16px` 的**简写**会把 padding-right 重置回去。
   ========================================================================== */
@media (min-width: 1025px) and (max-width: 1591px) {
    .hm-mid-link.is-media .hm-mid-text { padding-right: 52px; }
}

/* ==========================================================================
   AI 选型助手入口条（台账 #159 A / #171 A）—— 首屏 Hero 下方 + /select 页共用
   --------------------------------------------------------------------------
   形态：**一条 56px 的行**，输入框 flex:1 吃掉剩余宽度，三个方向按钮与提交键
   都在同一行内（JACK 2026-09-20 的硬约束：「缩短一点输入框，在一行内显示完」）。

   桌面（容器 1380）实测账：
     图标 16 + 输入框 ≈640 + 按钮组 ≈276 + 提交键 42 + 内边距/间隙 ≈46 = **≈1020px**
     ⇒ 落在 1380 里还余 350px 安全边距，不会因字体渲染差异挤爆。

   ★ 文案切换全部走 CSS（两套文案都渲染进 HTML）：
     ≥1025 显示全名（型号直查 / 按参数选型 / 应用方案）
     ≤1024 显示短名（查型号 / 查参数 / 查应用）—— 字数一样，宽度不变
   ★ 这条必须写在文件**最后**：`.ai-*` 是全新选择器，但 `.ai-bar-chips` 那几档
     media 的简写属性（padding / border-radius）会互相覆盖，后出现的才赢。
   ========================================================================== */

.ai-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 56px;
    /* 右内边距原为 7px —— 那是给 42px 圆形提交键留的视觉对称。
       2026-09-20 删掉那个键之后，右侧直接是按钮组，7px 会显得贴边 ⇒ 14px。 */
    padding: 7px 14px 7px 18px;
    border: 1px solid var(--hs-line-3);
    /* ★ 2026-09-20：原为 999px（胶囊）。JACK 按截图要求「改成方形的，和其它的一致」
       ⇒ 换成站内通行的 `--hs-radius`（2px，整站用了 32 处）。
       「方形」= 与其它盒子一致，不是 0 圆角。 */
    border-radius: var(--hs-radius);
    background-color: var(--hs-white);
    box-shadow: var(--hs-shadow);
}

/* ---- 名字（2026-09-20，JACK：「在输入窗放大镜左边加上名字，比如 AI小助」）----
   位置 = `.ai-bar` 的**第一个子元素**、放大镜左边 ⇒ 整条从"一个孤立的输入框"
   变成「AI小助 · 🔍输入框 · 三个方向按钮」，用户一眼知道这条是干什么用的。
   ★ 中英两套词只在**模板**里各写一份，与三颗按钮同一条纪律：文案的唯一出处是模板。
   ⚠ 名字是**纯标签**，不承担语义：屏幕阅读器念它无害，但"这里要输入什么"由输入框
     自己的 `aria-label`（"输入型号、参数或应用场景"）与三颗按钮的 `aria-pressed` 负责。
   ⚠ ≤560 隐藏：手机上名字一占位，输入框只剩约 100px，等于不可用 ——
     宁可少一个标签，也不能让这个条上唯一的输入口变窄。 */
.ai-bar-name {
    flex: none;
    font-size: 14px; font-weight: 700; letter-spacing: .2px;
    color: var(--hs-text);
    white-space: nowrap;
}

/* 放大镜：纯 CSS 画，不引图片、不加字重 */
.ai-bar-icon { position: relative; flex: none; width: 16px; height: 16px; }
.ai-bar-icon::before {
    content: ''; position: absolute; left: 0; top: 0;
    width: 10px; height: 10px; border: 1.6px solid var(--hs-text-mute); border-radius: 50%;
}
.ai-bar-icon::after {
    content: ''; position: absolute; right: 0; bottom: 1px;
    width: 7px; height: 1.6px; background-color: var(--hs-text-mute);
    transform: rotate(45deg); transform-origin: right center;
}

.ai-bar-input {
    flex: 1;
    min-width: 0;              /* ★ 不加这条，flex 子项不会收缩，输入框会把整行撑爆 */
    height: 40px;
    padding: 0;
    border: 0;
    outline: 0;
    font-size: 15px;
    color: var(--hs-text);
    background-color: transparent;
}
.ai-bar-input::placeholder { color: var(--hs-text-mute); font-size: 14px; }

.ai-bar-chips { display: flex; flex: none; gap: 6px; }

.ai-chip {
    display: inline-block;
    padding: 7px 13px;
    /* ★ 2026-09-20（JACK：「右边三个按钮加上细边框，提升一下质感」）：
       原来这里是 `1px solid transparent` —— 线宽 1px、颜色透明，只是给 hover 留位置。
       现在把颜色填上（`--hs-blue` 的 22% 不透明度），三颗按钮从"一片浅蓝贴纸"
       变成"带描边的按钮"。
       ⚠ **不产生任何布局位移**：`border-width` 本来就是 1px，这次只改颜色；而且全局
         `box-sizing: border-box` ⇒ 外框尺寸由 padding 决定，与边框**颜色**无关。 */
    border: 1px solid rgba(1, 105, 178, .22);
    border-radius: 999px;
    font-size: 14px;
    line-height: 1.3;
    white-space: nowrap;
    color: var(--hs-blue);
    background-color: var(--hs-blue-light);
    cursor: pointer;
    transition: background-color var(--hs-dur-2) var(--hs-ease), color var(--hs-dur-2) var(--hs-ease),
                border-color var(--hs-dur-2) var(--hs-ease);
}
.ai-chip:hover { background-color: var(--hs-blue-light); border-color: rgba(1, 105, 178, .45); }
/* 选中态：底色已经是实蓝，边框必须跟着变蓝 —— 否则一圈浅蓝描边浮在蓝底上会发灰 */
.ai-chip.is-on {
    color: var(--hs-white);
    background-color: var(--hs-blue);
    border-color: var(--hs-blue);
}
/* 短名默认藏起来；≤1024 由下面那档 media 换过来 */
.ai-chip-short { display: none; }

/* ★ 2026-09-20 删除 `.ai-bar-go`（右侧圆形箭头提交键）以及它的 ::before 箭头、
   hover / focus 三条规则。理由见 view/public/ai_entry.html 顶部注释：
   三个椭圆按钮本身就是 submit，那个键的"执行"职责与它们重复，
   保留它反而让人以为要先选类型再按箭头。
   ⚠ 删除功能默认连样式一起拿掉 —— 留着一条死规则，下一个人会以为还有这个按钮。 */

.ai-bar-input:focus-visible { outline: 2px solid var(--hs-blue); outline-offset: 0; border-radius: 4px; }
.ai-chip:focus-visible { outline: 2px solid var(--hs-blue); outline-offset: 2px; }

/* 入口条所在的区块：与下方分类区之间留出呼吸，不含任何背景色（不抢 hero 的注意力） */
/* ★ 2026-09-20（JACK 提：「AI 助手的宽度也和下面的栏目宽度不一样，应该保持一致的宽度」）：
   改前左右内边距是 **0**，于是 `.ai-bar` 这个框直接等于 `.hm-ai` 的整宽
   （1440 视口下 = 30..1395），而下面「产品分类」白底块有 40px 内边距、
   卡片实际落在 70..1355 ⇒ **AI 条比卡片列左边宽 40px、右边宽 40px**，
   一条横框压在两张卡的正上方却对不齐，看着就是歪的。
   改后左右都吃 `--hm-pad`（40 / 32 / 20 / 14 四档），框与卡片列**逐档等宽**：
   1440 下两者都是 70..1355（本条叠加 #207 的让位后同为 70..1343）。
   ⚠ 必须用变量而不是写死 40px：`.hm-cats` / `.hm-sec` 的左右也是
     `var(--hm-pad)`，四档 media 里会一起变；写死就只对齐一档。 */
.hm-ai { padding: var(--hs-sp-5) var(--hm-pad); }
.sl .ai-bar { margin-top: var(--hs-sp-4); }

/* ---- 768 ~ 1024：换成短名，**仍然一行** ---- */
@media (max-width: 1024px) {
    .ai-chip-full  { display: none; }
    .ai-chip-short { display: inline; }
    .ai-bar { min-height: 52px; padding: 6px 12px 6px 14px; }
    .ai-bar-input { height: 38px; font-size: 14px; }
    .ai-chip { padding: 6px 11px; font-size: 13px; }
}

/* ---- ≤560：名字给输入框让位 ----
   手机上「AI小助 + 🔍 + 三个短名按钮 + 内边距」已占掉约 290px，560 宽的窗口里
   输入框只剩 ~270px 尚可；再窄到 390 就只剩 ~100px ⇒ 名字直接收起，
   优先保证唯一的输入口可用。隐藏名字不损失功能（输入框的 aria-label 仍在）。 */
@media (max-width: 560px) {
    .ai-bar-name { display: none; }
}

/* ---- 1025 ~ 1591：**容器自己不让位**的入口条，靠内边距把内容收住 ----
   ★ 谁需要这条：入口条放在普通版心容器里的页面 —— 现在是 `/select`
     （`view/select/index.html` 把 `public/ai_entry` 直接 include 进 `.ct.sl`）。
     那类容器**没有右让位**，入口条**框**的右缘会落到挂件底下
     （1440 档实测：框右缘 1400、挂件左缘 1372 ⇒ 压 28px），
     只能靠内边距把**内容**提前收住，保证三颗按钮点得到。
   ★ 谁不需要：首页 —— `.hm-ai` 自己进了文件末尾的右让位规则，
     入口条的**框**已经避开挂件（1440 档实测框右缘 1358、挂件左缘 1372 ⇒ 净空 14px）。
   ★★ 所以这条**必须写成 `.sl .ai-bar`，不能写成 `.ai-bar`**：
     2026-09-20 我一度整条删掉，结果首页没事、`/select` 的按钮当场被压 13px
     （`_ai_bar_probe.js` 报红）。**首页和 `/select` 走的是两条不同的路** ——
     首页让"框"，`/select` 只能让"内容"，选择器收窄是唯一能同时成立的写法。
   ★ 数值 86 的来历（原台账 #191）：当时入口条框右缘 = 视口 − 30、挂件占视口最右
     76px（right 12 + 宽 64）⇒ 1440 档重叠 46px，第三颗按钮右端 31px 真的压在
     挂件图标上（`elementFromPoint` 命中挂件里的图标，不是观感）。
     72px = 46（重叠量）+ 14（基础右边距）+ 12（余量），取整 86。
   ★ ≤1024 不需要：那一档 `.sd` 已变成**底部固定条**（见上面 `.sd` 的 media）；
     ≥1592 不需要：挂件已经在版心右边缘之外。 */
@media (min-width: 1025px) and (max-width: 1591px) {
    .sl .ai-bar { padding-right: 86px; }
}

/* ---- ≤560：**允许按钮组折到第二行** ----
   ★ 这一档我明确**反对"强行一行"**：520 容器下三个按钮要占 ≈250px，
     硬塞进一行的结果是输入框只剩约 150px —— 用户根本看不见自己打的是什么。
     一个"看不见输入内容"的输入框比折成两行更糟。
   ⇒ 做法：输入框留在第一行（保住 ≥300px），三个按钮整组下移。
   ⚠ 原先这里把圆角放开到 16px（配合胶囊外框的"柔和"预期）。
     2026-09-20 外框改成 `--hs-radius` 之后，这一档**跟着基类走**，不再单独放宽 ——
     否则同一个控件在手机上是 16px、桌面是 2px，看着像两个东西。 */
@media (max-width: 560px) {
    .ai-bar {
        flex-wrap: wrap;
        gap: 8px;
        padding: 10px 12px 10px 14px;
    }
    .ai-bar-chips { order: 3; width: 100%; justify-content: flex-start; }
    .ai-bar-input { min-width: 140px; }
    .ai-chip { flex: none; }
}

/* ==========================================================================
   /select —— AI 选型助手结果页（台账 #159 A）
   --------------------------------------------------------------------------
   与 /search 共用 .ct / .ct-head / .ct-kicker / .ct-title / .ct-h2 / .ct-lede
   这一套骨架（`.ct` 的版心与间距已在上面定义），这里只补它自己那几种块。
   ========================================================================== */

.sl-note {
    margin: var(--hs-sp-3) 0 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--hs-text-3);
}
.sl-note strong { color: var(--hs-text-2); }

.sl-result, .sl-cand, .sl-recent, .sl-about, .sl-index, .sl-facets, .sl-drop {
    margin-top: var(--hs-sp-6);
}
.sl-h3 {
    margin: 0 0 var(--hs-sp-3);
    font-size: 15px;
    font-weight: 600;
    color: var(--hs-text);
}

/* 命中条件：把"我读懂了什么"逐条摊开，用户才能判断对不对 */
.sl-dims { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--hs-sp-4); padding: 0; list-style: none; }
.sl-dim {
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 13px;
    color: var(--hs-blue);
    background-color: var(--hs-blue-light);
}
.sl-dim-k { white-space: nowrap; }

.sl-go-wrap { margin: var(--hs-sp-4) 0 0; }
.sl-go {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 22px;
    border-radius: 999px;
    font-size: 15px;
    font-weight: 600;
    color: var(--hs-white);
    background-color: var(--hs-blue);
    transition: background-color var(--hs-dur-2) var(--hs-ease);
}
.sl-go:hover { background-color: var(--hs-blue); }
.sl-go-ghost { color: var(--hs-blue); background-color: var(--hs-blue-light); }
.sl-go-ghost:hover { color: var(--hs-white); background-color: var(--hs-blue); }
.sl-go-arrow {
    position: relative; flex: none; width: 10px; height: 10px;
    border-top: 2px solid currentColor; border-right: 2px solid currentColor;
    transform: rotate(45deg);
}

/* 未命中态的三条站内出路（#188 = 版式 A，2026-09-20）
   ★ 三列等宽、窄屏自动堆成一列 —— 用 auto-fit + minmax，不写三段媒体查询。
   ★ 用 minmax(220px, 1fr) 而不是裸 1fr：`1fr` 的最小值是 auto，
     里面那句长示例会把格子撑破（本站 .hm-cats 上栽过同一个坑）。
   ★ 卡片纵向 flex + 按钮 `margin: auto 0 0` ⇒ 三张卡文字长短不一时，
     三个按钮仍对齐在同一条水平线上（这是"三条并列"看起来整齐的关键）。 */
.sl-alt {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
    margin: var(--hs-sp-5) 0 0;
}
.sl-alt-item {
    display: flex;
    flex-direction: column;
    padding: var(--hs-sp-4) var(--hs-sp-5);
    border: 1px solid var(--hs-line-3);
    border-radius: 8px;
    background-color: var(--hs-white);
}
.sl-alt-k {
    margin: 0 0 8px;
    font-size: 15px;
    font-weight: 600;
    color: var(--hs-text);
}
.sl-alt-t {
    margin: 0;
    font-size: 14px;
    line-height: 1.7;
    color: var(--hs-text-2);
}
.sl-alt-eg {
    margin: 10px 0 0;
    font-size: 13px;
    line-height: 2;
    color: var(--hs-text-3);
}
.sl-alt-eg-lead { margin-right: 6px; color: var(--hs-text-mute); }
.sl-alt-eg-item {
    display: inline-block;
    margin-right: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background-color: var(--hs-bg);
    white-space: nowrap;
}
.sl-alt-go {
    margin: auto 0 0;
    padding-top: var(--hs-sp-4);
}
.sl-alt-go .sl-go { width: 100%; justify-content: center; }
@media (max-width: 560px) {
    .sl-alt-item { padding: var(--hs-sp-4); }
}

.sl-more { margin: var(--hs-sp-3) 0 0; font-size: 13px; color: var(--hs-text-3); }
.sl-more a { color: var(--hs-blue); }

.sl-arts { margin: 0; padding-left: 18px; }
.sl-arts li { margin-bottom: 8px; font-size: 14px; line-height: 1.7; }
.sl-arts a { color: var(--hs-blue); }
/* §200：应用搜索结果=文章列表 —— 条目右侧的发布日期（浅灰小字，不抢标题） */
.sl-arts-date { margin-left: 8px; font-size: 12px; color: var(--hs-text-3); }
/* §200：文章条目下的摘要（1~2 行浅灰正文，与标题同一列） */
.sl-arts-intro { margin: 2px 0 0; font-size: 13px; color: var(--hs-text-3); line-height: 1.7; }

/* #179 = D：没有采用的条件 —— 说清"为什么没用"，并给出**库里真实存在**的相邻档位 */
.sl-drop {
    padding: var(--hs-sp-4) var(--hs-sp-5);
    border-left: 3px solid var(--hs-orange);
    background-color: #fffaf3;
}
.sl-drop-list { margin: 0; padding: 0; list-style: none; }
.sl-drop-list li { margin-bottom: 10px; font-size: 13px; line-height: 1.8; }
.sl-drop-token {
    display: inline-block; margin-right: 8px; padding: 2px 8px;
    border-radius: var(--hs-radius); font-size: 12px;
    color: var(--hs-text-2); background-color: #efe6d8;
}
.sl-drop-why { color: var(--hs-text-3); }
.sl-drop-near { display: block; margin-top: 4px; color: var(--hs-text-3); }
.sl-drop-near a {
    display: inline-block; margin-right: 8px; padding: 3px 10px;
    border: 1px solid var(--hs-line-3); border-radius: 999px;
    font-size: 12px; color: var(--hs-blue); background-color: var(--hs-white);
}
.sl-drop-near a:hover { border-color: var(--hs-blue); }

.sl-notes { margin: var(--hs-sp-3) 0 0; padding-left: 18px; }
.sl-notes li { font-size: 13px; line-height: 1.7; color: var(--hs-text-3); }

/* 候选 / 索引：胶囊列表 */
.sl-chips { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; list-style: none; }
.sl-chip {
    display: inline-block;
    padding: 9px 16px;
    border: 1px solid var(--hs-line-3);
    border-radius: 999px;
    font-size: 14px;
    color: var(--hs-text-2);
    background-color: var(--hs-white);
    transition: border-color var(--hs-dur-2) var(--hs-ease), color var(--hs-dur-2) var(--hs-ease);
}
.sl-chip:hover { border-color: var(--hs-blue); color: var(--hs-blue); }
/* 静态项（"这个类别可筛哪些参数"）：不可点，所以要长得不像按钮 */
.sl-chip-static { border-style: dashed; color: var(--hs-text-3); cursor: default; }
.sl-chip-static:hover { border-color: var(--hs-line-3); color: var(--hs-text-3); }
.sl-hint { margin: var(--hs-sp-3) 0 0; font-size: 12px; color: var(--hs-text-mute); }

/* #177 = C：冷启动期的**格式示例**。
   ★ 刻意做成不可点的淡色提示（不是 chip）—— 可点就会被当成"可以选的型号"，
     那等于我们在推荐型号（与"不自行生产型号"的铁律相抵）。 */
.sl-fmt {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
    margin: var(--hs-sp-4) 0 0; font-size: 13px; color: var(--hs-text-mute);
}
.sl-fmt-prefix { color: var(--hs-text-mute); }
.sl-fmt-text {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 14px; letter-spacing: .4px; color: var(--hs-text-3);
}
.sl-fmt-tail { color: var(--hs-text-mute); }

.sl-about-list { margin: 0; padding-left: 18px; }
.sl-about-list li { margin-bottom: 8px; font-size: 14px; line-height: 1.8; color: var(--hs-text-2); }
.sl-about-list strong { color: var(--hs-text); }

@media (max-width: 768px) {
    .sl-drop { padding: var(--hs-sp-3) var(--hs-sp-4); }
    .sl-go { padding: 12px 18px; font-size: 14px; }
    .sl-chip { padding: 8px 14px; font-size: 13px; }
}

/* ==========================================================================
   询盘弹窗（台账 #192，2026-09-20）
   --------------------------------------------------------------------------
   由 main.js §3 动态创建外层 `.iq-modal`，内容来自 GET /inquiry/modal 的片段。
   ★ z-index 200 是**算出来的**，不是随手写的大数：站内现有最高的两个固定层是
     `.sd`（浮动联系挂件，60）和手机档的底部条（同一个 .sd，60）。
     弹窗必须同时压过它们，否则在 1025~1591 视口下挂件会浮在表单上面
     ——那正是 #191 那条遮挡缺陷的同一类问题。
   ★ 外层用 `position: fixed` 覆盖整屏并自己滚动（`overflow-y:auto`），
     而不是给 body 加 `overflow:hidden` 靠 JS 恢复：后者在 iOS 上会丢滚动位置。
   ========================================================================== */

.iq-modal {
    position: fixed;
    left: 0; right: 0; top: 0; bottom: 0;
    z-index: 200;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background-color: rgba(0, 0, 0, .45);
}

.iq-modal-box {
    position: relative;
    width: 100%;
    max-width: 760px;
    background-color: var(--hs-white);
    border-radius: var(--hs-radius);
    box-shadow: 0 8px 30px rgba(0, 0, 0, .18);
}
/* 取片段期间的高度占位 + 一条纯 CSS 进度条（不写文字，避免在 JS 里塞双语文案） */
.iq-modal-box.is-loading { min-height: 200px; }
.iq-modal-load {
    position: absolute; left: 0; right: 0; top: 0;
    height: 3px; overflow: hidden;
    background-color: var(--hs-line-2);
}
.iq-modal-load::after {
    content: ''; position: absolute; top: 0; left: -40%;
    width: 40%; height: 100%;
    background-color: var(--hs-blue);
    animation: iq-load 1s linear infinite;
}
@keyframes iq-load { from { left: -40%; } to { left: 100%; } }

.iq-modal-head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 15px 22px;
    border-bottom: 1px solid var(--hs-line);
}
.iq-modal-title { margin: 0; font-size: 19px; line-height: 1.4; color: var(--hs-text); }
.iq-modal-x {
    flex: none; width: 34px; height: 34px; margin: -4px -6px -4px 0; padding: 0;
    border: 0; background: none; cursor: pointer;
    font-size: 26px; line-height: 1; color: var(--hs-text-mute);
}
.iq-modal-x:hover { color: var(--hs-text); }
.iq-modal-body { padding: 20px 22px 24px; }

/* 成功回执：默认 hidden。★ 必须自己写 [hidden] 守卫 ——
   `.iq-modal-done` 一旦设了 display，就会盖掉浏览器默认的 [hidden]{display:none}。 */
.iq-modal-done { padding: 18px 0 6px; text-align: center; }
.iq-modal-done[hidden], .iq-form[hidden] { display: none !important; }
.iq-modal-done-t { margin: 0 0 8px; font-size: 18px; color: var(--hs-text); }
.iq-modal-done-b { margin: 0 0 20px; font-size: 14px; line-height: 1.8; color: var(--hs-text-3); }
.iq-modal-done-b b { color: var(--hs-text); font-weight: 700; }

/* `#194 = 1C`：令牌未满 3 秒时的「准备中…」态。
   ★ 刻意**不用** `pointer-events:none` —— 那会让 `elementFromPoint` 命中按钮背后的元素，
     探针 B6「提交按钮点得到」会直接假红。禁用靠 `disabled` 本身就够了。
   `:hover` 一并盖掉，是为了让按钮看起来"确实还不能按"。见 main.js 的 MIN_AGE_MS。 */
.iq-form .iq-submit[disabled],
.iq-form .iq-submit[disabled]:hover {
    background-color: var(--hs-orange);
    border-color: var(--hs-orange);
    opacity: .55;
    cursor: default;
}

@media (max-width: 768px) {
    /* 手机上不留白边：弹窗自己占满一屏、自己滚，避免"框里再套一个滚动区" */
    .iq-modal { padding: 0; }
    .iq-modal-box { max-width: none; min-height: 100%; border-radius: 0; }
    .iq-modal-head { padding: 12px 16px; }
    .iq-modal-body { padding: 16px; }
}

/* ==========================================================================
   右侧悬浮工具条 ②：让位与折叠（台账 #207 = A / #208 = A）
   --------------------------------------------------------------------------
   ★ 这两块**必须写在文件最后**，两个理由都踩过：
     ① 2518 / 2523 / 2551 / 2555 / 2643 / 2644 那几档 media 用的是
        `padding: var(--hs-sp-5) var(--hm-pad)` 这种**简写** —— 简写会把
        padding-right 一起写回默认值，所以同选择器的规则**后出现的才赢**
        （与 #167 / #191 注释里那条纪律一致）。
     ② `.sd.is-folded .sd-list` 要盖掉上面 `.sd-list` 的基础声明，同理。
   ========================================================================== */

/* ---- ① 让位（#207 = A「两边各让一点」）----
   实测几何（`analysis/_sd_geom_probe.js`，1440 视口 / clientWidth 1425）：
     · `.hm` 左右留白 30px ⇒ 白底块 `.hm-cats` / `.hm-sec` 右缘 = 视口 − 30
     · 白底块右内边距 40px ⇒ 最右一张 `.hm-card` 的**右边框** = 视口 − 70
     · 挂件 `.sd`：右 12px + 宽 64px ⇒ 左缘 = 视口 − 76
   ⇒ 卡片被压 6px、白底块被压 46px。**与视口宽基本无关**：
     版心 1440 封顶之前（≤1580）"视口 − 70" 这个值恒定，所以 1025~1500 一直是同一组数。
   ★ 让法：挂件右移 8px（12 → 4，见上面 `.sd` 的规则）＋ 白底块右内边距加 12px
     ⇒ 卡片右缘 = 视口 − 82、挂件左缘 = 视口 − 68 ⇒ **净空 14px**，
     第 4 列卡片的右边框完整露出来。
   ★ 为什么只加**内边距**、不动外框：白底块仍是整宽、仍与页面版心左右对齐，
     只有内容提前收住 —— 与 #191 对 `.ai-bar` 是同一手法。若改成给白底块加
     `margin-right`，整块会缩窄、左侧却不动，首页会明显看出"右边缺了一块"，
     那是另一个量级的改动。
   ⚠ `.hm-cats` 与 `.hm-sec` **必须成对**写。只写其中一个，两块的 `.hm-inner`
     宽度就不等，标题一变字号就看出左右错位（见 1721 行附近的说明）。
   ★ ≤1024 不需要：那一档 `.sd` 已变成屏幕底部横条，不占右侧。
   ★ 上界 1618 是算出来的，不是拍的：版心 1440 封顶后 `.hm-inner` 居中，
     右侧空白开始变宽。令 `clientWidth = 视口 − 15`（滚动条），
       `.sd.left = clientWidth − 68`
       封顶区 `.hm-card.right = 1510 + (clientWidth − 1580) / 2`
       ⇒ 净空 = `clientWidth / 2 − 788`
     取 ≥14px ⇒ `clientWidth ≥ 1604` ⇒ **视口 ≥ 1619**。
     （实测：1600 无本条时净空只剩 4.5px，就是这个临界区的尾巴。）
   ⚠ 这**不推翻 #106**（JACK 已定：正文被工具条压住按现状接受）。
     卡片边框被切是"看起来像坏了"，与正文被压的性质不同，只修前者。
     同理也没动 `.hm-mid` / `.hm-hero` 这两个**通栏横幅**的外框 ——
     它们本来就是整块的图/条，挂件压在上面属于设计预期。
   ★ `.hm-ai` 必须一起写进来：它的左右内边距也是 `var(--hm-pad)`，
     上面 2779 行刚按 JACK 的要求把它对齐到卡片列 —— 漏掉这一档，
     让位只在 `.hm-cats`/`.hm-sec` 上生效，AI 条又会比卡片宽 12px。 */
@media (min-width: 1025px) and (max-width: 1618px) {
    .hm-cats,
    .hm-sec,
    .hm-mid,
    .hm-ai { padding-right: calc(var(--hm-pad) + 12px); }

    /* ★ 2026-09-20（#214 = C）：这里**不需要**为分割线补任何修正 ——
       分割线挂在 `.hm-inner` 上（见 `.hm-sec` 定义后面那段），而 `.hm-inner` 本身就是
       上一行收过 12px 之后的那个内容列 ⇒ 线宽自动跟着收。
       第一版曾在这里补过 `::before { right: calc(var(--hm-pad) + 12px) }`，
       改成 `.hm-inner` 方案后已删（留着会成为一条永不生效的死规则）。 */

    /* ★★★ 2026-09-20（JACK：「hero 的 4 个按钮可以向左移一点，最右侧的按钮边框
       与下方 AI 助手右边框和下面的内容右边框」）—— hero 的**内容**也跟着收 12px。

       为什么偏偏 hero 要单独写一条：上面那四个块的 `padding-right` 是**区块自己的**
       内边距，它们的外框还有 `.hm` 的 `--hm-gutter` 夹着；hero 不一样 ——
       `.hm-hero` 用负外边距撑到通栏，`.hm-hero-slide` / `.hm-hero-cta` 的左右内边距
       是 `calc(--hm-pad + --hm-gutter)`，**自己就把那 30px 补回来了**。
       于是：
         区块内容右缘 = 视口 − (gutter + pad + 12) = 视口 − 82
         hero 内容右缘 = 视口 − (pad + gutter)   = 视口 − 70   ← 凸出 12px
       1440 档实测：最右那颗 CTA 按钮右边框 1355，而 AI 条框 / 卡片列都是 1343。

       证据链（JACK 那张截图 `clipboard-2026-09-20T12-54-41-456Z`，DPR 2）：
         他画的红线 = 图像 x 1300..1305，正好压在 **AI 条白框右缘 1298** 上；
         而 TechForum 按钮的右边框在图像 x≈1321~1323 ⇒ 越过红线 **24 图像 px = 12 css px**。
         ⇒ 他标的就是这 12px，判据与本地量测完全一致。

       ⚠ `.hm-hero-slide` 一起收：它是轮播里**每一张** slide 的容器
         （`flex: 0 0 100%` + 全局 border-box ⇒ 加 padding-right 不改外宽、不动 scroll-snap）。
         现在 hero 的 H1 / 导语与下方标题落在同一条左缘上，右缘也同列。
         不写它也不会出现可见错位（hero 文字是左对齐且限宽的），
         但「全页只有一个内容列」这条契约要能一条探针守住，就必须连它一起。
       ⚠ 只在 1025~1618 这一档生效：≥1619 时区块的让位本来就关掉了，
         hero 与它们自然同列；≤1024 挂件已变成底部横条，无需让位。 */
    .hm-hero-slide,
    .hm-hero-cta { padding-right: calc(var(--hm-pad) + var(--hm-gutter) + 12px); }
}

/* ---- ② 折叠把手（#208 = A 右缘竖标签把手 ／ #210 = 3B 竖排文字 → ★ #216 = C 已退回"只有箭头"）----
   形态：工具条**上方** 6px 处一个竖标签，与工具条右缘对齐。
   点它 → 工具条整条滑出屏幕右侧并淡出，只留这个标签；再点 → 滑回来。
   折叠状态记在 localStorage（见 main.js），刷新与翻页后保持。
   ★ 2026-09-20（#216 = C）：**退回"只有箭头"** —— `#210 = 3B` 加的那行竖排文字
     （「快捷联系 / Contact」）已从模板与样式里移除，尺寸回到 `#208` 定稿的 **28×68**。
     回退理由：34 宽的唯一作用是"放得下 11px 竖排字"；文字去掉之后，多出来的 6px
     就是纯占地 —— 工具条本体宽才 64px，把手不该比"收起"这个动作需要的宽度再宽一成。
     ⚠ 代价（JACK 已知并接受）：收起后右侧只剩一个 `‹`，新访客不一定知道那是什么。
       把它压到最小靠两点：① 箭头方向本身有语义（`›` = 收进去 / `‹` = 放出来）；
       ② 按钮的无障碍名一直由模板的 `data-label-*` 给出，从不依赖可见文字。

   ★ 三条设计决定，都是量出来的（#208 定，加文字后依然成立）：
     ① 把手用 `position: absolute` **挂在 `.sd` 的盒外**，不做 flex 子项 ——
        因为 `.sd` 是 `top:50% + translateY(-50%)` 垂直居中的：高度一变，
        整条会立刻重算中点、往下跳约 37px。absolute 不参与父级高度计算，
        所以"把手出现 / 把手变高（加文字）"**都不产生任何布局位移**。
     ② 把手在基础层是 `display:none`，由 JS 加 `.is-foldable` 才出现 ——
        与 `.sd-top` 同一条纪律：**没有 JS 时页面上不能有一个"点了没反应"的
        按钮**。≤1024 的底部横条上也不显示（那时工具条已经是横的）。
     ③ 过渡只挂在 `.sd.is-anim` 下（main.js 在首帧之后才加这个类）——
        否则"带着 localStorage 里的已折叠状态刷新页面"会被播成一次折叠动画：
        用户每翻一页都要看一遍工具条往里缩。
   ⚠ 折叠靠 `transform` 位移，不用 `display:none`：位移能动画，而且列表的
     **盒子仍然占位** ⇒ `.sd` 高度不变 ⇒ 把手不会跳到屏幕正中。
     收起态与展开态的把手在同一个位置，用户闭着眼也能点回原处。 */

.sd-fold { display: none; }

@media (min-width: 1025px) {
    .sd-fold {
        position: absolute; right: 0; bottom: calc(100% + 6px);
        /* ★ #216 = C：回到 `#208` 定稿的 28×68 —— 34×82 是 `#210 = 3B` 为"塞下竖排文字"放开的。 */
        width: 28px; height: 68px;
        display: none; align-items: center; justify-content: center;
        background-color: var(--hs-white); border: 1px solid var(--hs-line);
        color: var(--hs-text-2); cursor: pointer;
        transition: background-color var(--hs-dur-2) var(--hs-ease),
                    border-color var(--hs-dur-2) var(--hs-ease),
                    color var(--hs-dur-2) var(--hs-ease);
    }
    .sd.is-foldable .sd-fold { display: flex; }
    .sd-fold:hover { background-color: var(--hs-blue); border-color: var(--hs-blue); color: var(--hs-white); }
    .sd-fold-ico {
        flex: none;
        width: 9px; height: 9px;
        border-top: 2px solid currentColor; border-right: 2px solid currentColor;
        transform: rotate(45deg);                               /* › = 往右收 */
        transition: transform var(--hs-dur-2) var(--hs-ease);
    }
    /* ★ 2026-09-20（#216 = C）：这里原来是 `.sd-fold-txt`（竖排文字，`writing-mode: vertical-rl`
       + `white-space: nowrap`），已随 3B 一起移除。留下这行注释是为了可追溯 ——
       编号冻结、只标不回收：`#210 = 3B` 存在过，`#216 = C` 把它退掉了。 */
    .sd.is-folded .sd-fold-ico { transform: rotate(-135deg); }  /* ‹ = 放出来 */

    /* 折叠动画：滑动 + 淡出。`visibility` 要**等动画走完**再切，否则位移看不见；
       展开时 0s 立刻可见。动效降级交给 2106 行那条全局 `prefers-reduced-motion`
       （它把 transition-duration 压到 .01ms），这里不重复写一遍。 */
    .sd.is-anim .sd-list {
        transition: transform var(--hs-dur-3) var(--hs-ease),
                    opacity var(--hs-dur-3) var(--hs-ease),
                    visibility 0s linear 0s;
    }
    .sd.is-anim.is-folded .sd-list {
        transition: transform var(--hs-dur-3) var(--hs-ease),
                    opacity var(--hs-dur-3) var(--hs-ease),
                    visibility 0s linear var(--hs-dur-3);
    }
    .sd.is-folded .sd-list {
        transform: translateX(calc(100% + 8px));
        opacity: 0; visibility: hidden; pointer-events: none;
    }
}



/* ==========================================================================
   技术服务板块 `.sv-*`（2026-09-25，台账 §103 / #317~#325，JACK 拍板）
   ==========================================================================

## 命名空间
`.sv-*` 为第八套平行命名空间（hm/pd/cl/ct/tf/sl/iq/nf 之外新增），
不与任何现有前缀互套。

## 设计系统落点（§十二四语法）
· 区块大标题 28px 无装饰线（.sv-h2）；
· 卡片 = 1px var(--hs-line) + 3px var(--hs-blue) 顶边、直角（.sv-card）；
· 一屏只强调一件事：每页唯一强调点 = CTA 条（蓝底 + 橙按钮）；
· 区块间以内容留白分隔，块间细线只在 FAQ/清单处使用。

## 数据来源
模板零硬编码文案：全部来自 hs_service_section / hs_service_faq /
hs_service_cert（migration/76），后台「技术服务」可编辑。
   -------------------------------------------------------------------------- */
.sv {
    max-width: 1440px;
    margin: 0 auto;
}
.sv-hero {
    padding: 40px 40px 8px;
}
/* #333=A（2026-09-25 JACK）：母页 hero 图文横幅 —— 背景图来自广告位 services-banner，
   白字压图（左深右透渐变遮罩保证可读），橙色 CTA 按钮走设计系统橙。全直角。
   §136 高度缩到 191px；§137（2026-09-27 JACK）：回调到 240px。
   仅作用域 .sv-hero-banner，子页纯文字 hero（.sv-hero）不受影响。 */
.sv-hero-banner {
    position: relative;
    padding: 20px 40px;
    min-height: 240px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    background-color: #0f3f66;   /* 图加载前的兜底底色 */
    overflow: hidden;
}
.sv-hero-banner-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: right center;
}
.sv-hero-veil {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(10,35,58,0.78) 0%, rgba(10,35,58,0.45) 45%, rgba(10,35,58,0.05) 78%);
    z-index: 1;
}
.sv-hero-banner .sv-h1,
.sv-hero-banner .sv-lead {
    position: relative;
    z-index: 2;
    color: #ffffff;
}
/* §136：banner 收紧 —— h1 与导语的间距压缩（作用域限定，不影响子页）。
   导语限两行（§137 高度定在 240px；完整文案后台改短即可显示全） */
.sv-hero-banner .sv-h1 { margin-bottom: 4px; }
.sv-hero-banner .sv-lead {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: rgba(255,255,255,0.88);
    max-width: 760px;
}
/* §138（2026-09-27 JACK）：横幅上的橙色「立即咨询/Get Tech Support」按钮已删，
   .sv-hero-btn 全套规则随之移除；询盘入口由 CTA 条（services/_cta）与页脚承担。 */
.sv-h1 {
    margin: 0 0 14px;
    font-size: 28px;
    font-weight: 400;
    line-height: 1.3;
    color: var(--hs-text, #1a2b3c);
}
.sv-lead {
    margin: 0;
    /* 宽度统一（2026-09-25 JACK）：原 max-width:1080px 删 —— 与其它区块（1360 全宽）对齐，
       子页 hero 导语不再比下方区块窄一截 */
    font-size: 14px;   /* §140：15→14，与全站正文导语（ab-prose/dl-lead）统一 */
    line-height: 1.84;
    color: var(--hs-text-2, #5f6b7a);
}
.sv-group {
    padding: 28px 40px;
}
.sv-h2 {
    margin: 0 0 18px;
    font-size: 28px;
    font-weight: 400;
    line-height: 1.3;
    color: var(--hs-text, #1a2b3c);
}
.sv-group-desc {
    margin: -8px 0 18px;
    font-size: 14px;
    line-height: 1.7;
    color: var(--hs-text-2, #5f6b7a);
}

/* §138（2026-09-27 JACK）：组头横幅（#353=C 的「图 + 组名叠印」）撤销 ——
   设计服务/加工服务组头退回纯文字标题行（.sv-h2 + .sv-group-desc），
   .sv-group-banner / .sv-h2-banner 全套规则随之移除；
   组头 image 列数据仍保留在 hs_service_section（后台可见，不再被前台消费）。 */

/* ---- 服务流程（#353，2026-09-26 JACK：CTA 条与 FAQ 之间四步条） ----
   四步卡沿用设计系统语法②（1px 边 + 3px 蓝顶边，直角）；编号徽标 = 视觉锚点。 */
.sv-flow-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    list-style: none;
    margin: 18px 0 0;
    padding: 0;
}
.sv-flow-step {
    background-color: var(--hs-white, #fff);
    border: 1px solid var(--hs-line, #dde4ec);
    border-top: 3px solid var(--hs-blue, #0169b2);
    padding: 18px 20px 20px;
}
.sv-flow-num {
    display: block;
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    color: var(--hs-blue, #0169b2);
}
.sv-flow-title {
    margin: 12px 0 6px;
    font-size: 16px;
    font-weight: 700;
    color: var(--hs-text, #1a2b3c);
}
.sv-flow-desc {
    margin: 0;
    font-size: 14px;   /* §140：13.5→14，与全站正文统一 */
    line-height: 1.7;
    color: var(--hs-text-3, #8494a7);
}
@media (max-width: 1024px) {
    .sv-flow-list { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
    .sv-flow-list { grid-template-columns: 1fr; }
}
.sv-tagline {
    margin: -6px 0 16px;
    font-size: 14px;
    line-height: 1.7;
    color: var(--hs-blue, #0169b2);
}

/* ---- 能力卡（1px 边 + 3px 蓝顶边，直角） ---- */
.sv-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
}
.sv-cards-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.sv-cards-4 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.sv-cards-5 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.sv-card {
    display: block;
    position: relative;
    background: var(--hs-white, #fff);
    border: 1px solid var(--hs-line, #d8dee6);
    border-top: 3px solid var(--hs-blue, #0169b2);
    border-radius: 0;
    padding: 18px 20px 16px;
    color: inherit;
    text-decoration: none;
}
a.sv-card:hover .sv-card-title {
    color: var(--hs-blue, #0169b2);
}
.sv-card-title {
    margin: 0 0 8px;
    font-size: 17px;
    font-weight: 500;
    color: var(--hs-text, #1a2b3c);
}
.sv-card-en {
    margin: -4px 0 8px;
    font-size: 12px;
    letter-spacing: .02em;
    color: var(--hs-blue, #0169b2);
}
.sv-card-desc {
    margin: 0;
    font-size: 14px;   /* §140：13→14，与全站正文（ab-prose/dl-lead）统一 */
    line-height: 1.7;
    color: var(--hs-text-2, #5f6b7a);
}
/* §143：.sv-card-wide 已删（§135 后零引用） —— 见上方 sv-chips 处说明。 */
.sv-card-more {
    display: inline-block;
    margin-top: 14px;
    font-size: 13px;
    color: var(--hs-orange, #ff9415);
}
.sv-card-arrow {
    display: inline-block;
    margin-left: 6px;
    transition: transform .15s ease;
}
a.sv-card:hover .sv-card-arrow {
    transform: translateX(4px);
}
/* §143（2026-09-28）：.sv-card-wide（整宽卡）与 .sv-chips/.sv-chip（工序胶囊）已删
   —— §135 版式 A 落地后模板零引用（整宽卡升级为四工序图卡、胶囊退役）。 */

/* ---- §135 母页图文卡（2026-09-27 JACK 版式 A，migration/90 数据） ----
   设计服务 = 左图右文横卡；加工服务 = 四工序图卡；流程步卡加衔接线。
   直角、1px 边、无圆角（设计系统全站直角铁律）。 */
.sv-cards-design { grid-template-columns: repeat(2, 1fr); }
.sv-card-h { display: grid; grid-template-columns: 220px 1fr; padding: 0; overflow: hidden; }
.sv-card-hnoimg { grid-template-columns: 1fr; }   /* 无图降级：退化为纯文字卡 */
.sv-card-hmedia { display: block; min-height: 148px; }
.sv-card-hmedia img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sv-card-hbody { padding: 18px 20px 16px; min-width: 0; }
.sv-card-h .sv-card-more { margin-top: 10px; }

.sv-proc-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-top: 18px;
}
.sv-proc-card {
    display: block;
    background: var(--hs-white, #fff);
    border: 1px solid var(--hs-line, #d8dee6);
    border-radius: 0;
    color: inherit;
    text-decoration: none;
}
.sv-proc-media {
    display: block;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-bottom: 1px solid var(--hs-line, #d8dee6);
}
.sv-proc-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .2s ease;
}
a.sv-proc-card:hover .sv-proc-media img { transform: scale(1.04); }
a.sv-proc-card:hover .sv-proc-name { color: var(--hs-blue, #0169b2); }
/* 减薄/切割槽位（免费图库无真实素材）：蓝调占位块，后台填图即出图 */
.sv-proc-slot {
    display: flex;
    height: 100%;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #e8f1f8 0%, #d3e4f2 100%);
    color: var(--hs-blue, #0169b2);
    font-size: 15px;
    letter-spacing: .08em;
}
.sv-proc-name {
    display: block;
    padding: 12px 14px 0;
    font-size: 16px;   /* §140：15→16，与流程步卡标题（sv-flow-title）统一 */
    font-weight: 700;
    color: var(--hs-text, #1a2b3c);
}
.sv-proc-tag {
    display: block;
    padding: 4px 14px 14px;
    font-size: 13px;   /* §140：12.5→13，辅助小字统一档 */
    line-height: 1.6;
    color: var(--hs-text-3, #8494a7);
}
/* 流程步卡衔接线：只在桌面四列排布下画（窄屏折行后线会指空） */
.sv-flow-step { position: relative; }
@media (min-width: 1025px) {
    .sv-flow-step:not(:last-child)::after {
        content: '';
        position: absolute;
        top: 50%;
        right: -17px;
        width: 18px;
        border-top: 1px dashed var(--hs-blue, #0169b2);
    }
}
@media (max-width: 1024px) {
    .sv-cards-design { grid-template-columns: 1fr; }
    .sv-proc-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .sv-proc-grid { grid-template-columns: 1fr; }
    .sv-card-h { grid-template-columns: 1fr; }
    .sv-card-hmedia { min-height: 0; aspect-ratio: 16 / 9; }
}

/* ---- 步骤条（流程）：CSS 计数器编号 ---- */
.sv-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: sv-step;
}
.sv-step {
    position: relative;
    display: flex;
    gap: 16px;
    padding: 0 0 18px 0;
}
.sv-step:last-child { padding-bottom: 0; }
.sv-step-no {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border: 1px solid var(--hs-blue, #0169b2);
    color: var(--hs-blue, #0169b2);
    font-size: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.sv-step-no::before {
    content: counter(sv-step);
    counter-increment: sv-step;
}
.sv-step-body { min-width: 0; }
.sv-step-name {
    margin: 2px 0 6px;
    font-size: 15px;
    font-weight: 500;
    color: var(--hs-text, #1a2b3c);
}
.sv-step-desc {
    margin: 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--hs-text-2, #5f6b7a);
}

/* ---- 名词清单（名称|说明） ---- */
.sv-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.sv-list-item {
    display: flex;
    gap: 14px;
    padding: 12px 0;
    border-bottom: 1px solid var(--hs-line, #d8dee6);
}
.sv-list-item:last-child { border-bottom: 0; }
.sv-list-name {
    flex: 0 0 168px;
    font-size: 14px;
    font-weight: 500;
    color: var(--hs-text, #1a2b3c);
}
.sv-list-text {
    min-width: 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--hs-text-2, #5f6b7a);
}

/* ---- 整块说明（标题|大段说明，晶圆加工能力块用） ---- */
.sv-blocks {
    display: grid;
    gap: 14px;
}
.sv-block {
    background: var(--hs-bg, #f4f7fb);
    border: 1px solid var(--hs-line, #d8dee6);
    padding: 16px 20px;
}
.sv-block-name {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 500;
    color: var(--hs-text, #1a2b3c);
}
.sv-block-desc {
    margin: 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--hs-text-2, #5f6b7a);
}

/* ---- 散文段（Why us / 质量承诺） ---- */
.sv-prose {
    margin: 0;
    /* 宽度统一（2026-09-25 JACK）：原 max-width:1080px 删，同 .sv-lead */
    font-size: 14px;
    line-height: 1.84;
    color: var(--hs-text-2, #5f6b7a);
}

/* §143（2026-09-28）：合作邮箱块 .sv-contact/-title/-body 三条已删 —— 模板零引用
   （grep view/app + DB 富文本双重核实），渲染不受影响。 */

/* ---- CTA 条（一屏唯一强调点） ---- */
.sv-cta {
    display: flex;
    align-items: center;
    gap: 24px;
    background: var(--hs-blue, #0169b2);
    padding: 22px 28px;
}
.sv-cta-title {
    margin: 0;
    font-size: 17px;
    font-weight: 500;
    color: #fff;
}
.sv-cta-desc {
    margin: 0;
    font-size: 13px;
    color: rgba(255, 255, 255, .78);
}
.sv-cta-btn {
    margin-left: auto;
    flex: 0 0 auto;
    background: var(--hs-orange, #ff9415);
    color: #fff;
    text-decoration: none;
    font-size: 14px;
    padding: 10px 22px;
}
.sv-cta-btn:hover { filter: brightness(1.05); }

/* ---- FAQ（<details> 原生折叠，无 JS 也可读可爬） ---- */
.sv-faq-list {
    border-top: 1px solid var(--hs-line, #d8dee6);
}
.sv-faq-item {
    border-bottom: 1px solid var(--hs-line, #d8dee6);
    background: var(--hs-white, #fff);
}
.sv-faq-q {
    position: relative;
    list-style: none;
    cursor: pointer;
    padding: 14px 44px 14px 2px;
    font-size: 14px;
    font-weight: 500;
    color: var(--hs-text, #1a2b3c);
}
.sv-faq-q::-webkit-details-marker { display: none; }
.sv-faq-mark::before,
.sv-faq-mark::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 14px;
    width: 12px;
    height: 2px;
    background: var(--hs-blue, #0169b2);
    transform: translateY(-50%);
    transition: transform .15s ease;
}
.sv-faq-mark::after { transform: translateY(-50%) rotate(90deg); }
.sv-faq-item[open] .sv-faq-mark::after { transform: translateY(-50%) rotate(0deg); }
.sv-faq-a {
    padding: 0 44px 16px 2px;
    font-size: 13px;
    line-height: 1.8;
    color: var(--hs-text-2, #5f6b7a);
}

/* ---- 证书（母页区块，sv_cert_show 开关 + 0 行不渲染） ---- */
.sv-cert-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 16px;
}
.sv-cert {
    margin: 0;
    background: var(--hs-white, #fff);
    border: 1px solid var(--hs-line, #d8dee6);
    padding: 12px;
}
.sv-cert img {
    display: block;
    width: 100%;
    height: auto;
}
.sv-cert-title {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--hs-text-2, #5f6b7a);
    text-align: center;
}
.sv-cert-zoom { display: block; cursor: zoom-in; }

/* ---- 证书大图弹出层（main.js §9 data-sv-zoom，无 JS 时 <a> 原生打开图片） ---- */
.sv-lightbox {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 20, 30, .72);
    cursor: zoom-out;
}
.sv-lightbox img {
    max-width: min(92vw, 980px);
    max-height: 88vh;
    background: #fff;
    padding: 8px;
}

/* ---- 窄屏（≤1024）：右缘白名单不生效区间，与 .ct/.cl 同款回落 ---- */
@media (max-width: 1024px) {
    .sv-hero, .sv-group { padding-left: 20px; padding-right: 20px; }
    .sv-cta { flex-wrap: wrap; gap: 12px; }
    .sv-cta-btn { margin-left: 0; }
    .sv-list-item { flex-direction: column; gap: 4px; }
    .sv-list-name { flex-basis: auto; }
}

/* ---- 产品详情页 → 技术服务的内链（#319-④ 站内权重导入） ---- */
.pd-sv-link {
    margin: 14px 0 0;
    font-size: 13px;
}
.pd-sv-link a {
    color: var(--hs-blue, #0169b2);
    text-decoration: none;
}
.pd-sv-link a:hover { text-decoration: underline; }

/* ---- 区块级配图（#326 烧录配图等；migration/77 image 列） ---- */
.sv-fig {
    margin: 0 0 16px;
    border: 1px solid var(--hs-line, #eeeeee);
    background: var(--hs-white, #fff);
    overflow: hidden;
}
.sv-fig img {
    display: block;
    width: 100%;
    max-width: 760px;
    height: auto;
}

/* ==========================================================================
   ★★ 全站内容页右缘让位（2026-09-21，`#246 = A`「扩成全站内容页约束」）
   ==========================================================================

## 这条治什么
右侧悬浮工具条 `.sd` 是 `position:fixed; right:4px; width:64px` ⇒ **左缘 = 视口 − 68**。
1025~1618 视口区间里，`.cl` / `.ct` / `.pd` / `.tf` / 页脚这些页型的内容是**流式的**
（页根无左右内边距、内部白块自带 `padding: … 40px`）⇒ 内容右缘 = 视口 − 30~40，
比 `.sd` 的左缘**还靠右 28~38px**，于是最右一列被压住。

实测（探针 `analysis/_cl_edge_probe.js`，改前）：
  · 品类页 `/cn/products/tvs-diodes`：1440 −13px / 1100 −19px / 1025 −19px（受害 = 筛选最右列的计数数字）
    滚动后 −8px（受害 = 产品表最右的操作按钮）
  · 详情页：页脚 `服务时间：8:30-18:30（工作日）` −13.9px
  · 选型页 `/select`：`.sl-chip「家用电器」` −34px
  · 首页 ✔ —— 它早有 §十一 那条规则（`hm-*`），**其它页型没继承**。

## 为什么值取 82px
首页定下的不变量是「**内容/框右缘 = 视口 − 82**」（68 + 净空 14）。
内容页要达到同一条列，就把各内容块的右内边距**定为 82px**
（它们都挂在零内边距的页根上，所以 `padding-right` 直接等于「距视口右缘的距离」）。
副作用是好的：改前 `.cl-head`(40) 与 `.cl-row`(20) 的右缘本来就对不齐，改后**都落在 82** ⇒ 反而更整齐。

## 边界
· 只在 **1025~1618** 生效：≤1024 时 `.sd` 已变成整宽底部横条（无需让位）；
  ≥1619 时版心 1440 封顶，净空本来就有（实测 1680 档净空 +107px）。
· **只动"内容块"的右内边距，不动白底块本身的宽度** —— 白底块右缘仍在视口 − 30/0，
  与首页「背景块接受被压」的口径（`#106`）一致。
· 必须写在**文件末尾**：前面几档 media 用 `padding` 简写重置过内边距，写早了会被覆盖。
   -------------------------------------------------------------------------- */

/* ==========================================================================
   资料下载枢纽页 .dl-*（#355，2026-09-26「方案一 + 全站循环」）
   --------------------------------------------------------------------------
   · 命名空间：dl-（八套平行命名空间的第九套，与其余页型互不嵌套）；
   · 卡片语法②：1px --hs-line + 3px --hs-blue 顶边、直角；
   · 容器口径照 .sv：max-width 1440 居中，区块自带 40px 横向内边距；
   · 1025~1618 右缘净空：.dl-head / .dl-sec 已加进文件末尾的白名单
     （那一条必须保持在文件最后，本段因此只能写在它前面）。
   ========================================================================== */
.dl {
    max-width: 1440px;
    margin: 0 auto;
    padding-bottom: 56px;
}
.dl-head {
    /* §137（2026-09-27 JACK）：退回 §136 以前的白底文字头（深蓝横幅头撤销），
       白底深字、无最低高度 —— 恢复 #355 落地时的原样。 */
    padding: 44px 40px 38px;
}
.dl-h1 {
    margin: 0;
    font-size: 28px;
    font-weight: 400;
    color: var(--hs-text);
    line-height: 1.4;
}
.dl-lead {
    margin: 10px 0 0;
    font-size: 14px;
    color: var(--hs-text-2);
    line-height: 1.8;
}
.dl-sec {
    padding: 24px 40px 0;
}
.dl-sec-h {
    margin: 0 0 14px;
    font-size: 20px;
    font-weight: 400;
    color: var(--hs-text);
    padding-bottom: 8px;
    border-bottom: 3px solid var(--hs-blue);
    display: inline-block;
}

/* ① 搜索卡 */
.dl-card {
    background: var(--hs-white);
    border: 1px solid var(--hs-line);
    border-top: 3px solid var(--hs-blue);
    padding: 22px 24px;
}
.dl-card-h {
    margin: 0 0 14px;
    font-size: 17px;
    font-weight: 400;
    color: var(--hs-text);
}
.dl-search {
    display: flex;
    gap: 10px;
}
.dl-search-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 1px solid var(--hs-line-3);
    padding: 10px 14px;
    font-size: 14px;
    color: var(--hs-text);
    background: #fff;
    border-radius: 0;
}
.dl-search-input:focus {
    outline: none;
    border-color: var(--hs-blue);
}
.dl-search-btn {
    flex: 0 0 auto;
    border: 0;
    background: var(--hs-blue);
    color: #fff;
    font-size: 14px;
    padding: 10px 30px;
    cursor: pointer;
    border-radius: 0;
}
.dl-search-btn:hover {
    background: var(--hs-blue-dark);
}

/* 多命中列表（封顶 12 条 + 真实总数，不翻页） */
.dl-hit-note {
    margin: 14px 0 0;
    font-size: 13px;
    color: var(--hs-text-2);
}
.dl-hits {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    border-top: 1px solid var(--hs-line);
}
.dl-hit {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 9px 2px;
    border-bottom: 1px solid var(--hs-line);
    font-size: 13px;
}
.dl-hit-main {
    flex: 1 1 auto;
    min-width: 0;
}
.dl-hit-model {
    color: var(--hs-blue);
    text-decoration: none;
    overflow-wrap: anywhere;
}
.dl-hit-model:hover {
    text-decoration: underline;
}
/* 匹配型号副行（型号→文件映射层带出；文件名直接命中无此行） */
.dl-hit-sub {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--hs-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dl-hit-more,
.dl-nomatch {
    margin: 12px 0 0;
    font-size: 13px;
    color: var(--hs-text-2);
    line-height: 1.8;
}
.dl-hit-more a,
.dl-nomatch a {
    color: var(--hs-blue);
    text-decoration: none;
}
.dl-hit-more a:hover,
.dl-nomatch a:hover {
    text-decoration: underline;
}

/* 热门型号 / 品类 chips */
.dl-hot,
.dl-catrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--hs-line);
}
.dl-hot-label,
.dl-catrow-label {
    font-size: 13px;
    color: var(--hs-text-2);
}
.dl-hot-tag {
    font-size: 13px;
    color: var(--hs-blue);
    text-decoration: none;
    border: 1px solid var(--hs-blue);
    padding: 4px 12px;
}
.dl-hot-tag:hover {
    background: var(--hs-blue-light);
}
.dl-cat {
    font-size: 13px;
    color: var(--hs-blue);
    text-decoration: none;
    border: 1px solid var(--hs-line-3);
    padding: 4px 12px;
}
.dl-cat:hover {
    border-color: var(--hs-blue);
}
.dl-cat-n {
    color: var(--hs-text-3);
    margin-left: 5px;
}

/* ② 证书卡 */
.dl-cert-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 14px;
}
.dl-cert {
    background: var(--hs-white);
    border: 1px solid var(--hs-line);
    border-top: 3px solid var(--hs-blue);
    padding: 14px;
}
.dl-cert-img {
    display: block;
    border: 1px solid var(--hs-line);
    background: #fff;
}
.dl-cert-img img {
    display: block;
    width: 100%;
    height: 180px;
    object-fit: contain;
}
.dl-cert-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
}
.dl-cert-name {
    font-size: 13px;
    color: var(--hs-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dl-cert-dl {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--hs-blue);
    text-decoration: none;
    border: 1px solid var(--hs-blue);
    padding: 4px 14px;
}
.dl-cert-dl:hover {
    background: var(--hs-blue-light);
}

/* ③ 工具入口卡 */
.dl-tool-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 14px;
}
.dl-tool {
    display: block;
    position: relative;
    background: var(--hs-white);
    border: 1px solid var(--hs-line);
    border-top: 3px solid var(--hs-blue);
    padding: 18px 44px 18px 20px;
    text-decoration: none;
}
.dl-tool:hover {
    border-color: var(--hs-blue);
}
.dl-tool-name {
    display: block;
    font-size: 15px;
    color: var(--hs-blue);
}
.dl-tool-desc {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    color: var(--hs-text-2);
    line-height: 1.7;
}
.dl-tool-go {
    position: absolute;
    right: 18px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 18px;
    color: var(--hs-blue);
}

/* ②' 规格书文件库：资料库类别夹直读（#355 业务逻辑第 2 条） */
.dl-lib-note {
    margin: 0 0 12px;
    font-size: 13px;
    color: var(--hs-text-2);
}
.dl-catnav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 18px;
}
.dl-catnav-tag {
    font-size: 13px;
    color: var(--hs-blue);
    text-decoration: none;
    border: 1px solid var(--hs-line-3);
    padding: 4px 12px;
}
.dl-catnav-tag:hover {
    border-color: var(--hs-blue);
}
.dl-catnav-tag.is-active {
    border-color: var(--hs-blue);
    background: var(--hs-blue-light);
}
.dl-lib-group {
    margin-top: 20px;
}
.dl-lib-h {
    margin: 0 0 8px;
    font-size: 16px;
    font-weight: 400;
    color: var(--hs-text);
}
.dl-lib-n {
    margin-left: 8px;
    font-size: 12px;
    color: var(--hs-text-mute);
}
.dl-lib-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--hs-line);
}
.dl-lib-item {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 8px 2px;
    border-bottom: 1px solid var(--hs-line);
    font-size: 13px;
}
.dl-lib-name {
    color: var(--hs-blue);
    text-decoration: none;
    min-width: 0;
    overflow-wrap: anywhere;
}
.dl-lib-name:hover {
    text-decoration: underline;
}
.dl-lib-size {
    color: var(--hs-text-mute);
    flex: 0 0 auto;
    margin-left: auto;
}
.dl-lib-dl {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--hs-blue);
    text-decoration: none;
    border: 1px solid var(--hs-blue);
    padding: 2px 12px;
}
.dl-lib-dl:hover {
    background: var(--hs-blue-light);
}

/* 类别列表翻页（#355 二轮：每类一屏 18 份） */
.dl-lib-pager {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 14px;
}
.dl-lib-pager a,
.dl-lib-pager .dl-pager-cur {
    font-size: 12px;
    color: var(--hs-text);
    text-decoration: none;
    border: 1px solid var(--hs-line-3);
    padding: 4px 10px;
    line-height: 1.5;
}
.dl-lib-pager a:hover {
    border-color: var(--hs-blue);
    color: var(--hs-blue);
}
.dl-lib-pager .dl-pager-cur {
    background: var(--hs-blue);
    border-color: var(--hs-blue);
    color: var(--hs-white);
}

@media (max-width: 768px) {
    .dl-head,
    .dl-sec {
        padding-left: 20px;
        padding-right: 20px;
    }
    .dl-search {
        flex-direction: column;
    }
}

/* ==========================================================================
   关于我们 .ab-* / 联系我们 .co-*（#358，2026-09-27 #361~#363=A）
   --------------------------------------------------------------------------
   · 命名空间：ab- / co-（与 hm/pd/cl/ct/tf/sl/iq/dl 平行，互不嵌套）；
   · 深蓝页头照版式稿（#361=A）：--hs-blue-dark 大底白字（首页 hero 同源色）；
   · 卡片语法②：1px --hs-line-3 + 3px --hs-blue 顶边、直角；
   · 容器口径照 .dl：max-width 1440 居中，区块自带 40px 横向内边距；
   · 富文本结构：正文由 hs_content#85/#4 提供（migration/87），页面级区块
     是 .ab/.co 的**直接子级** .ab-sec/.co-sec，富文本内部同名 .ab-sec
     走 margin 口径 —— 白名单里只列直接子级（.ab > .ab-sec），防止双层 82px。
   · 1025~1618 右缘净空：白名单条目加在文件末尾（见下）。
   ========================================================================== */
.ab,
.co {
    max-width: 1440px;
    margin: 0 auto;
    padding-bottom: 56px;
}

/* 深蓝页头（版式稿 #361=A） */
/* §136（2026-09-27 JACK）：内页 banner 大小对调 —— About 调大到原 /services 大图横幅
   体量（实测 351px）；Services/TechForum/Downloads 三个模块缩到原 .ab-head 体量。
   §137（同日 JACK 修订）：About 页头定高 = 首页 hero 渲染高度（.hm-hero-slide
   min-height 380px）；Downloads 撤销横幅头退回白底（见 .dl-head）。
   co-head（/contact）不在本次范围，维持原样。 */
.ab-head {
    background: var(--hs-blue-dark);
    color: var(--hs-white);
    padding: 44px 40px;
    /* §149（2026-09-29 JACK）：/about banner 高度减少 25% ⇒ 380 × 0.75 = 285。
       §137 的「= 首页 hero 380 同基准」口径在 /about 页就此覆盖（首页 hero 不动） */
    min-height: 285px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    box-sizing: border-box;
}
.co-head {
    background: var(--hs-blue-dark);
    color: var(--hs-white);
    padding: 44px 40px 38px;
}
.ab-head-en,
.co-head-en {
    margin: 0;
    font-size: 12px;
    letter-spacing: 3px;
    color: rgba(255, 255, 255, .62);
}
.ab-h1,
.co-h1 {
    margin: 10px 0 0;
    font-size: 30px;
    font-weight: 400;
    line-height: 1.35;
    color: var(--hs-white);
}
.ab-lead,
.co-lead {
    margin: 12px 0 0;
    font-size: 15px;
    line-height: 1.8;
    color: rgba(255, 255, 255, .85);
    max-width: 860px;
}

/* 富文本正文容器（hs_content 内容 |raw 渲染落点） */
.ab-page {
    padding: 32px 40px 0;
}
/* §149（2026-09-29 JACK）：company profile 文章内容宽度 = 1250 居中。
   白名单（1025~1618）给 .ab-page 的 68 内边距在本页撤销 —— 用 (0,2,0) 压过 (0,1,0)；
   桌面横向内边距归零 ⇒ 1250 就是净内容宽；≤1024 的 24px 回落在下方媒体块单独保回。
   ★ 只动正文容器：入口卡 / CTA 条仍是 1304（页宽 − 68），没让动就不动。 */
.ab .ab-page {
    max-width: 1250px;
    margin: 0 auto;
    padding-left: 0;
    padding-right: 0;
}
/* §149-b（2026-09-29 JACK「收齐到 1250」）：入口卡 / CTA 条与正文同一网格。
   不动 .ab-sec 的白名单内边距（避免特异性打架），给两个内容盒限宽居中：
   在 1304 内容区里居中 ⇒ 左缘 = 68 + 27 = 95，与 .ab-page 完全同线。
   ★ 只在 .ab 作用域 —— /contact 的 co-links / co-cta-in 不动。 */
.ab .ab-links,
.ab .ab-cta-in {
    max-width: 1250px;
    margin-left: auto;
    margin-right: auto;
}

/* 页面级区块（CTA 条 / 入口卡）：.ab/.co 直接子级才带横向内边距 */
.ab > .ab-sec,
.co > .co-sec {
    padding: 28px 40px 0;
}
/* 页尾区块收边（/contact CTA、/about CTA —— 2026-09-27 入口卡上移后 CTA 落尾） */
.co-sec-last,
.ab-sec-last {
    padding-bottom: 8px !important;
}

/* 富文本内部区块：只管纵向节奏，横向由 .ab-page 管 */
.ab-body .ab-sec {
    margin: 0 0 40px;
}
.ab-sec-h {
    margin: 0 0 18px;
    /* §144：20→28 —— 区块大标题统一 28px（与 .sv-h2 同标准，§十二） */
    font-size: 28px;
    font-weight: 400;
    color: var(--hs-text);
    /* §139（2026-09-27 JACK）：标题下蓝色下划线去掉 —— 纯文字标题
       （原 padding-bottom 8px + border-bottom 3px 蓝线一并移除） */
}
.ab-prose {
    max-width: 1080px;
}
.ab-prose p {
    margin: 0 0 14px;
    font-size: 14px;
    line-height: 1.9;
    color: var(--hs-text-2);
}
.ab-h3 {
    margin: 20px 0 10px;
    font-size: 16px;
    font-weight: 400;
    color: var(--hs-text);
    padding-left: 12px;
    border-left: 3px solid var(--hs-blue);
}

/* 产品系列卡（3 栏）/ 应用领域块（4 栏）：语法② */
.ab-grid {
    display: grid;
    gap: 16px;
}
.ab-grid-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.ab-grid-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
.ab-card {
    background: var(--hs-white);
    border: 1px solid var(--hs-line-3);
    border-top: 3px solid var(--hs-blue);
    padding: 18px 20px;
}
.ab-card-h {
    margin: 0 0 6px;
    font-size: 16px;
    font-weight: 400;
    color: var(--hs-text);
}
.ab-card-en {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--hs-text-mute);
}
.ab-card-t {
    margin: 0;
    font-size: 13px;
    line-height: 1.8;
    color: var(--hs-text-2);
}
.ab-app {
    background: var(--hs-bg);
    padding: 16px 18px;
}
.ab-app-h {
    margin: 0 0 6px;
    /* §144：15→16 —— 卡片标题统一 16px（与 .ab-card-h/.ab-h3 一致） */
    font-size: 16px;
    font-weight: 400;
    color: var(--hs-text);
}
.ab-app-t {
    margin: 0;
    font-size: 13px;
    line-height: 1.8;
    color: var(--hs-text-2);
}

/* CTA 条（about 深蓝 / contact 浅灰，同一动作橙钮） */
.ab-cta-in {
    background: var(--hs-blue-dark);
    color: var(--hs-white);
    padding: 24px 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
}
.ab-cta-t {
    margin: 0;
    font-size: 17px;
}
.ab-cta-d {
    margin: 4px 0 0;
    font-size: 13px;
    color: rgba(255, 255, 255, .78);
}
.ab-cta-btn,
.co-cta-btn {
    flex: 0 0 auto;
    background: var(--hs-orange);
    color: var(--hs-white);
    padding: 12px 26px;
    font-size: 14px;
    text-decoration: none;
}
.ab-cta-btn:hover,
.co-cta-btn:hover {
    background: var(--hs-orange-dark);
    color: var(--hs-white);
}
.ab-cta-arrow,
.co-cta-arrow {
    margin-left: 8px;
}

/* 联系卡（电话 / 邮箱 / 地址） */
.co-cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}
.co-card {
    background: var(--hs-white);
    border: 1px solid var(--hs-line-3);
    border-top: 3px solid var(--hs-blue);
    padding: 20px 22px;
}
.co-card-wide {
    grid-column: 1 / -1;
}
.co-card-h {
    margin: 0 0 10px;
    font-size: 14px;
    font-weight: 400;
    color: var(--hs-text-2);
}
.co-card-v {
    margin: 0;
    font-size: 18px;
    line-height: 1.7;
    color: var(--hs-text);
}
/* 地址行单独缩一号（2026-09-29 JACK：地址字体小一点；电话/邮箱维持 18px） */
.co-card .co-card-addr {
    font-size: 15px;
}
.co-card-en {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--hs-text-mute);
}
a.co-card-v {
    color: var(--hs-blue);
    text-decoration: none;
}
a.co-card-v:hover {
    text-decoration: underline;
}

/* contact CTA 条（2026-09-29 JACK：加可见背景 = 淡蓝底；与 about 深蓝条区分） */
.co-cta {
    background: #e8f1f9;
    border: 1px solid var(--hs-line);
    padding: 22px 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.co-cta-t {
    margin: 0;
    font-size: 16px;
    color: var(--hs-text);
}
.co-cta-d {
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--hs-text-2);
}

/* 入口卡（工作机会 / 新闻 / 联系我们 · 资料下载 / 技术服务 / 关于我们） */
.ab-links,
.co-links {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
}
.ab-linkcard,
.co-linkcard {
    display: block;
    background: var(--hs-white);
    border: 1px solid var(--hs-line-3);
    border-top: 3px solid var(--hs-blue);
    padding: 18px 20px;
    text-decoration: none;
}
.ab-linkcard-h,
.co-linkcard-h {
    display: block;
    font-size: 16px;
    color: var(--hs-blue);
}
/* 2026-09-29 JACK：contact 入口卡小标题加粗（about 页 .ab-linkcard-h 未动，要同步说一声） */
.co-linkcard-h {
    font-weight: 700;
}
.ab-linkcard:hover .ab-linkcard-h,
.co-linkcard:hover .co-linkcard-h {
    text-decoration: underline;
}
.ab-linkcard-t,
.co-linkcard-t {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    line-height: 1.8;
    color: var(--hs-text-2);
}

/* 窄屏回落（≤1024 同 .dl 口径） */
@media (max-width: 1024px) {
    .ab-head,
    .co-head,
    .dl-head,
    .ab-page,
    .ab > .ab-sec,
    .co > .co-sec {
        padding-left: 24px;
        padding-right: 24px;
    }
    /* §149：.ab .ab-page (0,2,0) 的横向 0 内边距会把上面 (0,1,0) 的 24px 压掉，
       窄屏必须用同级特异性保回，否则移动端正文贴边 */
    .ab .ab-page {
        padding-left: 24px;
        padding-right: 24px;
    }
    .ab-head,
    .co-head {
        padding-top: 32px;
        padding-bottom: 30px;
    }
    .ab-grid-4,
    .ab-links,
    .co-links {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
@media (max-width: 768px) {
    .ab-grid-3,
    .ab-grid-4,
    .ab-links,
    .co-links,
    .co-cards {
        grid-template-columns: 1fr;
    }
    .ab-h1,
    .co-h1 {
        font-size: 24px;
    }
    .ab-cta-in,
    .co-cta {
        flex-direction: column;
        align-items: flex-start;
    }
}

@media (min-width: 1025px) and (max-width: 1618px) {
    /* 品类页 `.cl-*`
       ★★ 2026-09-21 重要修正：原来这里列了 `.cl-toolbar / .cl-list-head / .cl-row /
       .cl-entries / .cl-jump / .cl-empty` 六个，**它们一个都没生效** ——
       这六个都在 `.cl-body` 里，而 CSS 前面对它们写的是**双类选择器**
       （`.cl-body .cl-toolbar{padding:0 0 20px}` / `.cl-body .cl-empty{padding:50px 20px}`），
       特异性 (0,2,0) 压过这里的单类 (0,1,0) ⇒ 覆盖失败。
         · `.cl-toolbar` / `.cl-empty` ⇒ 净空只剩 40/60px，**实测搜索框被 `.sd` 压住**；
         · 另外四个（`.cl-list-head`/`.cl-row`/`.cl-jump`/`.cl-entries`）反而是
           `40+82=122px`，**过度留白 40px**（探针只判"被压"、不判"留白过多"，所以没报）。
       ⇒ 正确口径：**`.cl-body` 内的东西由 `.cl-body` 一个内边距统一管**，
         不再逐个列 —— 少一层特异性打架，也不会再多一处漏网。
       `.cl-head` / `.cl-filter` / `.cl-tabs` 在 `.cl` 直下（`.cl` 自身左右无内边距），
       仍是各自带 40px，必须单独补到 82。 */
    .cl-head,
    .cl-filter,
    .cl-tabs,
    .cl-body,
    /* ★ 2026-09-21 补漏：`.cl-overview`（参数档位一览）在 `.cl` 直下、**不在 `.cl-body` 里**，
       它自己 `padding: 40px` 四方向 ⇒ 右内边距 40 而不是 82。
       实测内容右缘 R1400，其它块 R1358 ⇒ **比邻居多伸出 42px**，
       这正是 JACK 说的「一个页面上有好多种不同宽度的框」。 */
    .cl-overview,
    /* 内容页 / 搜索页 / 选型页 `.ct-*` */
    .ct-head,
    .ct-subs,
    .ct-body,
    .ct-list-wrap,
    .ct-pager,
    .ct-empty,
    .ct-cover,
    .ct-related,
    /* 技术社区 `.tf-*` */
    .tf-wrap,
    .tf-tabs,
    .tf-article,
    .tf-detail-grid,
    /* 产品详情页 `.pd` */
    .pd,
    /* 选型页 `/select` 的六个 section —— ★ 与上面 `.ct-*` 不同：
       它们**自己不带内边距**（`.sl-result,…{ margin-top }` 那条只有 margin），
       内容右缘直接顶到 `.ct` 容器边 ⇒ 也必须补到 82，否则最右那一刻胶囊被压。
       （2026-09-21 补：改前这里剩 `.sl-chip「家用电器」` 净空 −34px，是唯一漏网的一处。） */
    .sl-result,
    .sl-cand,
    .sl-facets,
    .sl-recent,
    .sl-about,
    .sl-index,
    /* 询盘页 / 404 */
    .iq-page,
    .nf,
    /* 技术服务板块 `.sv-*`（#317~#325）
       `.sv-hero` / `.sv-group` 是仅有的两个自带横向内边距的内容块，
       其余块都挂在 `.sv-group` 里 —— 与 `.cl-body` 同一条收敛口径 */
    .sv-hero,
    .sv-group,
    /* 资料下载枢纽页 .dl-*（#355）：.dl-head / .dl-sec 是仅有的两个
       自带横向内边距的内容块 —— 与 .sv 同一条收敛口径 */
    .dl-head,
    .dl-sec,
    /* 关于我们 .ab-* / 联系我们 .co-*（#358）：页头与页面级区块。
       ★ 富文本内部的 .ab-sec 不进白名单 —— .ab-page 已带 82，
         再列进去就是双层 82px（特异性同为 (0,1,0)，靠子级选择器避开）。 */
    .ab-head,
    .ab-page,
    .ab > .ab-sec,
    .co-head,
    .co > .co-sec,
    /* 页脚（全站都有） */
    .ft-main,
    .ft-bottom {
        /* §140-A（2026-09-28 JACK）：全站统一 左 68 / 右 68 / 居中 ——
           原口径左 40/右 82 造成「左窄右宽」全站性不对等；82 改 68 后内容右缘
           = 视口−68，与右缘悬浮条 .sd（右 4px + 宽 64 = 左缘视口−68）正好贴合
           （原 82 留 14px 缝，现贴线，实测见 _typo_geom_140.js）。
           内容宽 1440−136=1304。左 68 与右对称 ⇒ 内容居中。
           >1618 容器定宽居中、≤1024 移动端小边距，均本就对称，不受影响。 */
        padding-left: 68px;
        padding-right: 68px;
    }
}
