/* ============================================================
 * 智企办公 · 客户端页面内容区版式（public/client/styles/pages.css）
 * ------------------------------------------------------------
 * 位置：客户端目录 —— 商家端**不得引用**。
 * 承接 shell.css：shell.css 管**顶部外壳与基础组件**；
 * 本文件管**页面内容区版式**（商品卡 / 详情页签 / 规格网格 / 购物车提交栏 /
 * 相似推荐卡 / 商品目录表 / 目录双栏分类板块 / 返回按钮 / 购物车抽屉 #cart-drawer）。
 * 🔴 作用域纪律：本端靠 `.cat-*` / `.prod-*` / `.cb-*` / `#cart-drawer` 等**本端专属前缀**
 *    与 id 作用域隔离，不逐个加 `.shell.hc-c`。实测两端**无同名裸类冲突**：
 *    `.toolbar` / `.searchbox` / `.tbl` 等共用名在商家端一律带 `.shell.hc-m` 前缀。
 * 由 client.css 按轴拆分而来（2026-10-07 阶段④）；未改一字，仅搬移位置。
 * ============================================================ */

/* ---------- 商品卡 / 详情 ---------- */
.prod-main{display:flex;gap:22px}
.price-line{display:flex;align-items:baseline;gap:10px}
.detail-tabs{display:flex;border-bottom:1px solid var(--line);margin:14px 0}
.detail-tabs button{padding:9px 18px;font-size:14px;color:var(--t3);border-bottom:2px solid transparent;font-weight:600}
.spec-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 26px}
.acc-row{display:flex;align-items:center;gap:12px;background:var(--sf2);border-radius:10px;padding:10px 12px;margin-bottom:8px;flex-wrap:wrap}
/* ===== 【2026-10-14 掌柜指令】详情页「适配配件」行：加购按钮**常驻最右边** =====
 * 掌柜原话：「加入购物车按钮，常驻最右边」。改前实测（`_assess/tmp/acc-row/`，商品 `xSN000026`）：
 *   行高 **115.6px**、**换行了**（4 个不同的 offsetTop），按钮 `offsetLeft=65`（第二行最左），
 *   **右缘距行右内边 438px** —— 因为基础规则是 `flex-wrap:wrap`，而名称块内联 `min-width:150px`、
 *   `.desc` 又有 `flex:1;min-width:180px`（base.css:304）⇒ 三块加起来放不下就把按钮挤到下一行。
 * 🔴🔴 `.acc-row` 是**共用类**（`ent-center.js` 的成员行 / 头像行也用）⇒ 一律**只加修饰类**，
 *   不动基础规则；选择器统一写 `.acc-row.acc-link`（(0,2,0) > `.acc-row`(0,1,0)，且 pages.css 后于 base.css）。
 * 🔴 走 **flex + `flex-wrap:nowrap`**（不改用 grid）：按钮 `flex:0 0 auto` 恒定不收缩 ⇒ 永远贴右；
 *   名称块 `flex:1 1 auto` 吃剩余、备注 `flex:0 1 auto` 按内容宽。
 *   ⚠️ 试过 grid(`auto minmax(0,1fr) auto auto`)：它能贴右，但 `auto` 列会额外吃到不该吃的宽度
 *   （实测备注列 180px 而文字只要 60px），把名称块从 351 压到 231、商品名断行很难看 ⇒ 弃用。
 * 🔴 旧版按钮换行的真实原因：`flex-wrap:wrap` ＋ 名称块**内联** `min-width:150px` ＋ base.css:304 的
 *   `.desc{flex:1;min-width:180px}` 三样叠加，三块放不下就把按钮挤到第二行（实测行高 115.6、按钮距右缘 438px）。 */
.acc-row.acc-link{display:flex;flex-wrap:nowrap;align-items:center}
/* 名称块：吃剩余空间；`min-width:0` 允许收缩，`overflow:hidden` 兜住被压到极小时的溢出
 * （备注「不收缩」⇒ 极限窄屏下这里可能只剩几十像素，不能让文字溢到按钮上）。 */
.acc-row.acc-link .acc-main{flex:1 1 auto;min-width:0;overflow:hidden}
/* 商品名：最多两行，超出省略（名称块可被压缩，但不能把行撑破） */
.acc-row.acc-link .an{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 备注：**按内容宽**排、单行、上限 38% 宽。🔴 三处都不能省：
 *   · `width:max-content` —— 把基准尺寸**明确写成内容宽**。只写 `flex:0 0 auto` 时 flex-basis:auto 会回退到
 *     `width:auto`，浏览器取「受百分比 max-width 约束的尺寸」⇒ 实测元素宽直接变成 **180px**（=38%），
 *     把名称块从 351 压到 231、行高 94→113（比不改还差）。
 *   · `flex:0 0 auto` —— 不收缩：空间不足时**先牺牲名称块宽度**（它的 `.an` 本来就有两行容量），
 *     备注始终完整；改前 base 的 `flex:1` 正是把按钮挤下去的另一半原因。
 *   · `min-width:0` —— 🔴 **最容易漏的一条**：base.css:304 的 `.acc-row .desc{…min-width:180px}` 是给
 *     「wrap 版」写的；不覆盖它，无论 `flex` / `width` 怎么设，元素都**至少 180px**（实测就卡在这：
 *     desc 恒 180、名称块被压到 231、行高 94）。四条一起写才对。
 *   · `max-width:38%` —— 长备注的上限（超出走省略号），同时压住极端窄屏的溢出。 */
.acc-row.acc-link .desc{flex:0 0 auto;width:max-content;min-width:0;max-width:38%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 按钮：不收缩 + `margin-left:auto` 双保险贴右 */
.acc-row.acc-link .btn-mini{flex:0 0 auto;margin-left:auto;white-space:nowrap}
/* ---------- 购物车 / 提交栏 ----------
 * 2026-10-25：这里原有 `.cart-layout` 的「1fr + 342px 两栏」定义，已删除。
 * 该口径先后被 base.css §11b（2026-09-17 改单列）与本文件 §十九（2026-10-25 改回
 * 两栏 380px）以更高特异性覆盖 ⇒ 早已不生效，属于「同选择器被后者静默覆盖」那类死代码。
 * 栅格定义现只存在 §十九 19.1 一处。 */
/* ---------- 相似推荐大卡（详情页 v2 优化） ---------- */
.sim-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(256px,1fr));gap:14px;margin-top:14px}
.sim-in{font-size:12px;color:var(--ok-ink);background:var(--ok-weak);border-radius:999px;padding:3px 10px;font-weight:600;white-space:nowrap}
.zoom-hint{position:absolute;left:0;right:0;bottom:0;padding:8px 0;text-align:center;font-size:12px;color:#fff;background:linear-gradient(transparent,rgba(15,23,42,.55));pointer-events:none;opacity:0;transition:opacity .15s}
/* .sp-pick-card 已随 2026-10-14「右栏分区块」下线（内层卡片去 card 化，改 .pd-blk-spec）。
 * 🔴 不能保留原规则：它此前的 padding 一直被 `.shell.hc-c .card`(0,2,0) 压死、是**死值**；
 *    去掉内层 card 后它会突然生效，在白卡里造成二次缩进。 */
/* ============ 客户端商品目录（单表）：订货编码列 = 商品主编码；SKU 订货编码仅在弹窗/详情/订单明细 ============ */
.cat-tbl td{vertical-align:middle;padding:14px 14px}
.cat-tbl .cat-seq{color:var(--t4);font-size:12px;text-align:center;font-variant-numeric:tabular-nums}
/* ===== 客户端商品目录：字号适当放大（相对全局表格 +1~2px） ===== */
.cat-tbl{font-size:14px}
.cat-tbl th{font-size:12px;font-weight:700}
.cat-tbl td{font-size:14px}
.cat-tbl .cat-seq{font-size:14px}
.cat-tbl .cat-code{font-size:14px}
.cat-tbl .btn-mini{height:32px;font-size:12px;padding:0 12px}
/* ===== 客户端返回按钮（商品详情 / 订单详情页头） ===== */
.btn-back{display:inline-flex;align-items:center;gap:5px;height:32px;padding:0 13px;border:1px solid var(--line2);border-radius:9px;background:#fff;color:var(--t3);font-size:14px;font-weight:600;text-decoration:none;cursor:pointer;transition:border-color .15s,color .15s,background .15s;white-space:nowrap;flex-shrink:0}
.btn-back:hover{color:var(--pri-600);border-color:var(--pri);background:var(--pri-weak,#F0F5FF)}
.back-row{margin:2px 0 12px}
/* 目录缩略图 60×60 + 行距紧凑（仅商品目录表） */
.cat-tbl td{padding:9px 12px}
.cat-tbl thead th{padding-top:9px;padding-bottom:9px}
/* 【2026-10-14 掌柜指令】目录商品行**整行可点**进商品详情 ⇒ 行显示手型（否则看不出能点）。
 * 🔴 行内的星标 / 「加入购物车」按钮 / 商品名链接各自带自己的 data-act（click 委派 `closest` 内层胜出），
 *   它们本来就该是手型 ⇒ **不需要**光标复位 —— 与详情页规格行不同，本行内**没有文本输入框**。
 * ⚠️ 若日后往行内加 `<input>`/`<select>`，光标与「点它会不会跳走」两件事都要重新想（见 catalog.js 注释）。 */
.cat-tbl tbody tr{cursor:pointer}
/* 【2026-10-25 掌柜指令】商品名允许折到**两行**（原来单行 nowrap，实测 19/20 条标题被省略）。
 * 只在商品目录表放开：选择器与 base.css:2217 的 `.shell.hc-c .cat-tbl .cat-prod-n` 同特异性，
 * 本文件在 index.html 里**后于** base.css 加载 ⇒ 同特异性下必胜（不是靠 !important）。
 * 🔴 行高不变：两行标题 16px×1.3×2 ≈ 42 + 间距 4 + 编码行约 17 ≈ 63px，仍小于
 *    「缩略图 60 + 上下内距 18 = 78px」⇒ 撑高行的仍是缩略图。改这几项前先重算这个和，否则整表会突然变稀。
 * ⚠️ 必须用 `-webkit-box` 才能 line-clamp；`display:block` 配 `-webkit-line-clamp` 不生效，
 *    会退化成「单行不省略」直接溢出到相邻列。 */
.shell.hc-c .cat-tbl .cat-prod-n{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  white-space:normal;overflow:hidden;word-break:break-word;line-height:1.3;
}
/* ===== 【2026-10-14 掌柜指令】购物车行**整行可点** → 右侧滑出商品详情（与商品目录同一套机制）=====
 * 掌柜原话：「点击购物车里面的明细，那个商品详情采用右侧滑出的方式，与商品目录那款完全一致」。
 * 🔴 作用域必须带 `.cart-layout`：`.cart-tbl` 是**共用类** —— 客户端「我的订单」(#c-orders .ov-tbl)
 *   与**商家端**订单表(_shell-orders.js)都在用它（见 base.css §cart-tbl）。裸写 `.cart-tbl tbody tr`
 *   会把那两张表也变成「看着能点、其实点不动」。
 * 🔴 与目录行不同：本行**有文本输入框**（.qty-inp）⇒ 「数量 / 所属部门 / 操作」三格挂了
 *   `data-act="row-hold"`（点进去**不跳转**），光标随之复位；格内真正可点的控件（± / 换规格 / 删除 /
 *   部门触发器）各自保留手型 —— `button` 有全局 `cursor:pointer`（base.css:86），
 *   `.qty-inp` 单独退回文本光标（`cursor` 是**继承**属性，所以只需在三格上复位一次）。 */
.cart-layout .cart-tbl tbody tr{cursor:pointer}
.cart-layout .cart-tbl tbody td[data-act="row-hold"]{cursor:auto}
.cart-layout .cart-tbl tbody td[data-act="row-hold"] .qty-inp{cursor:text}
/* 800px 购物车抽屉（#cart-drawer）的行卡同理，只是行根由 <tr> 换成 .cd-row。 */
#cart-drawer .cd-row{cursor:pointer}
#cart-drawer .cd-row [data-act="row-hold"]{cursor:auto}
#cart-drawer .cd-row [data-act="row-hold"] .qty-inp{cursor:text}
/* ---------- 购物车「幽灵行」提示条（2026-10-15 第三组 #18 · 掌柜裁定） ----------
 * 商品已不可购买（已下架 / 已移出本企业授权）的行会在装入状态时被整行剔除，本条负责**显式告知**。
 * 🔴 原先把 margin/padding/配色写成**内联 style**，触发 precheck「危险/状态色走了内联 style」告警 ——
 *   状态色一律走样式表（本仓红线）。两个载体共用：整页 .cart-layout 与 800px 抽屉 .cd-list。 */
.shell.hc-c .cart-note{margin:0 0 12px;padding:10px 14px;border-radius:var(--r-md);
  background:var(--warn-weak);color:var(--warn);font-size:13px;line-height:1.6}
.shell.hc-c .cd-list > .cart-note{margin:0 0 10px}
/* ===== 商品目录双栏：左侧 260px 分类导航树 + 右侧商品表（2026-09-08 重构） ===== */
.cat-flex{display:flex;align-items:flex-start;gap:16px;margin-top:4px}
/* 悬浮阴影仅随 hc-cat-page 视口布局的固定卡条常驻（见文末媒体块）；基础滚动布局卡条随页滚动不吸顶、不遮挡 */
.nt-arrow{flex:0 0 24px;width:24px;height:24px;border-radius:999px;border:1px solid var(--line2);background:var(--canvas);color:var(--t3);font-size:15px;line-height:1;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:all .14s ease;opacity:.8;flex-shrink:0}
.nt-arrow:hover{background:var(--pri-weak);color:var(--pri-600);border-color:var(--pri-100);opacity:1}
.nt-arrow:active{transform:scale(.93)}
.cat-tree{width:460px;flex:0 0 460px;box-sizing:border-box;background:#fff;border:1px solid var(--line);border-radius:14px;padding:10px;height:calc(100vh - var(--vh-chrome-nav));max-height:calc(100vh - var(--vh-chrome-nav));overflow-y:auto;position:sticky;top:138px;scrollbar-width:thin}
/* 【2026-10-14 死 CSS 清理】原「客户端目录左栏：商城式分类板块」那版的结构说明与全部规则
 * （`.cb-top` 复位条 / `.cb-sec` 板块 / `.cb-h` 大标题 / `.cb-cnt` 计数 / `.cb-grid` 栅格 /
 *  `.cb-tile` 图卡 / `.cb-th` 缩略图 / `.cb-n` 名称 / `.cb-pill` 胶囊）**已整体删除** ——
 *  左栏现役结构见上方 `.cat-tree` 与 `.cat-*` 系列。留此一句只为保留「这里曾有过什么」的线索。 */
.cat-main{flex:1;min-width:0}
#cart-drawer .cd{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:12px}
#cart-drawer .cd-list{flex:1 1 auto;min-height:0;overflow:auto;background:#fff;border:1px solid var(--line);border-radius:14px;overscroll-behavior:contain}
#cart-drawer .cd-row{display:flex;align-items:center;gap:12px;padding:12px}
#cart-drawer .cd-row + .cd-row{border-top:1px solid var(--line3)}
#cart-drawer .cd-thumb{flex:0 0 56px;width:56px;height:56px;border-radius:10px;overflow:hidden;display:flex;align-items:center;justify-content:center;background:var(--sf);border:1px solid var(--line);font-size:17px;font-weight:600;color:var(--t5)}
#cart-drawer .cd-mid{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
#cart-drawer .cd-nm{font-size:14px;font-weight:600;color:var(--ink);display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#cart-drawer .cd-nm:hover{color:var(--pri-600);text-decoration:underline}
#cart-drawer .cd-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:11.5px;color:var(--t4);line-height:1.6}
#cart-drawer .cd-pre{font-size:11px;font-weight:600;color:var(--warn-ink)}
#cart-drawer .cd-ops{display:flex;align-items:center;gap:8px;font-size:12px}
#cart-drawer .cd-right{flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
#cart-drawer .cd-right .cd-amt{font-size:15px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
/* 【2026-10-15 D 组 · 兼修上一批的回归】预询行（缺货 · 待定价）的**统一呈现类**。
 * 🔴 为什么必须在这里补一条：BLK-4 把购物车两态的预询标记统一成 cartAmtCell 产出的 `.cd-pre-wait`，
 *   但**漏了给它写样式** —— 改前整页版用行内 `style="color:var(--warn-ink);font-weight:600"`、
 *   抽屉版用 `#cart-drawer .cd-right .cd-amt .wait`；统一成一个新类却没人定义它
 *   ⇒ 两处的「待商家定价」**都退化成无样式的黑字**（警示色与字重同时丢失）。
 *   这是「视觉类改动判据全绿 ≠ 改动有效」的又一实例：当时只截了有价格变更的行，
 *   没截预询行，所以两支探针都没照出来。
 * 字号刻意不写：整页版跟随 td 的 14px（与改前的行内写法一致），抽屉版另行还原 13px（见下条）。 */
.cd-pre-wait{color:var(--warn-ink);font-weight:600;font-style:normal}
/* 抽屉版金额格的字号单独还原 —— 改前 `.wait` 是 13px，而 `.cd-amt` 自身是 15px/700，
 * 不覆盖的话「待商家定价」会比原来的现货金额明显大一截。 */
#cart-drawer .cd-right .cd-amt .cd-pre-wait{font-size:13px}
#cart-drawer .cd-qty{display:flex;align-items:center;gap:8px}
/* 「换规格」与数量同行；固定 52px 槽位 —— 单规格商品没有它，留空占位才能让各行步进器落在同一个 x */
#cart-drawer .cd-slot{flex:0 0 52px;width:52px;height:30px;display:flex;align-items:center;justify-content:center;font-size:12px}
#cart-drawer .cd-empty{text-align:center;padding:52px 20px;font-size:13px;color:var(--t4)}
#cart-drawer .cd-sum{flex:0 0 auto;height:64px;display:flex;align-items:center;gap:8px;background:#fff;border:1px solid var(--line);border-radius:14px;padding:0 16px}
#cart-drawer .cd-sum-lb{font-size:13px;color:var(--t3)}
#cart-drawer .cd-sum-amt{font-size:24px;font-weight:800;color:var(--pri-600);font-variant-numeric:tabular-nums;margin-right:auto}
#cart-drawer .cd-sum-cnt{font-size:12px;color:var(--t4);white-space:nowrap}
#cart-drawer .cd-form{flex:0 0 auto;display:flex;flex-direction:column;gap:12px;background:#fff;border:1px solid var(--line);border-radius:14px;padding:16px}
#cart-drawer .cd-ent{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--t4)}
#cart-drawer .cd-ent b{font-size:13px;font-weight:600;color:var(--ink)}
#cart-drawer .cd-div{height:1px;background:var(--line3)}
#cart-drawer .cd-fd{display:flex;flex-direction:column;gap:5px;position:relative;min-width:0}
#cart-drawer .cd-lb{font-size:12px;font-weight:500;color:var(--t2)}
#cart-drawer .cd-fd .err-txt{position:absolute;left:2px;bottom:-14px;font-size:11px}
#cart-drawer .cd-2col{display:flex;gap:14px}
#cart-drawer .cd-2col .cd-fd{flex:1 1 0}
#cart-drawer .cd-foot{flex:0 0 auto;height:72px;display:flex;align-items:center;justify-content:space-between;gap:12px;background:#fff;border:1px solid var(--line);border-radius:14px;padding:0 16px}
#cart-drawer .cd-exp{display:flex;align-items:center;gap:8px;font-size:12.5px}
/* 表格自适应：旧的「按列序号隐藏列」规则已删除（2026-09-14）。
 * 它的原目标是序号列(1) 与 单位列(7)，但客户端表格早已没有序号列，
 * 于是这条规则实际藏掉的是**商品列**；本轮又新增了星标列(1)、供货状态并列(7)，
 * 继续保留会把新列误伤。现改为：表格定宽 + 容器内横向滚动，不隐藏任何列。 */
/* 徽章降级：目录行供货状态 = 圆点 + 文字（状态徽章样式仍用于详情/其它页） */
.cat-tbl .st-cell{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:var(--t2);white-space:nowrap}
/* ≤1400：容器宽度不足以固定 550（实测 1440 时 .cat-main 恰为 704 = 550+下拉 134+两 gap 20，刚好容纳），
 * 此时回退为可收缩 —— 工具条是 nowrap，不收缩就会把页面撑出横向滚动条。 */
@media (max-width:1366px){
  .shell.hc-c .cat-main .toolbar .searchbox{flex:0 1 550px;min-width:100px}
}

/* ============================================================
 * 商品详情页 · 两栏宽版（2026-10-11）
 * 版式：左栏 = 图集（竖排缩略图 + 大图）+ 页签与内容；右栏 = 购买信息（常驻吸顶）。
 * 🔴 两条硬约束：
 *   ① 1440 版心（左 700 + 间距 40 + 右 700）只落在本包裹层 —— `.content` 是**全站滚动域**
 *      （目录/购物车/订单共用），绝不能给它加 max-width；
 *   ② 右栏 sticky 要求祖先链（.pd-wrap / .pd-cols / .pd-buy）**不得 overflow**，
 *      且 .pd-buy 必须 align-self:start —— grid 默认 stretch 会让它没有可滚动行程，吸顶直接失效。
 * 作用域：`.hc-cdetail` 只由整页壳带（detailView 的 shellC 第 4 参）；
 *   抽屉壳是 `.hc-cat-page`，天然不带 —— 于是同一份 HTML 在抽屉里按容器宽度自适应，无需分支。
 * ============================================================ */
/* 版心：**1440 = 左 700 + 间距 40 + 右 700**（掌柜 2026-10-11 指定「左右布局各 700px」）。
 * **不用媒体查询** —— max-width 在窄屏本来就不生效：宽屏封顶 1440，窄屏自动收缩到可用宽度。 */
.pd-wrap{margin:0 auto;max-width:1440px}
/* 详情页两侧留白收窄（客户端全站是 48px，见 base.css:925）。
 * 详情页内容密度高（图集 + 规格行 + 长详情），48px 会把可用宽度吃掉 96px ⇒ 常见 1366/1440 屏上根本到不了 1440。 */
/* 🔴🔴 2026-10-14 掌柜报障：切页签时商品图「抖动、稍微有一点变大」= **滚动条槽位**在反复占位/让位。
 *   链路（逐环实测，取证 `_assess/tmp/pd-tabjit/`）：切页签 → 左栏内容高变 → `.content` 的 8px
 *   竖向滚动条**出现/消失** → 内容盒宽 1436 ⇄ 1444 → `.pd-cols` 是 `repeat(2,minmax(0,1fr))`
 *   ⇒ 每列 ±4px → 商品图（`aspect-ratio:1/1`）**宽高各 ±4px**（实测 674×674 ⇄ 678×678 @1460×1200）。
 *   掌柜原话：「图片区，它就是一个图片区，它是固定的。然后底下的商品详情、规格参数、适配配件或者相似推荐，
 *   它就吸在这个图片的底下……不能因为这个底下的页签来回切换、因为页签的内容多了少了，而导致整个页面抖动变化。」
 * 🔴 修法 = `scrollbar-gutter:stable`：槽位**恒占**，内容宽与「内容多少」彻底解耦。
 * 🔴🔴 **为什么不一刀切给全站 `.content`**：`overflow:hidden` 的容器**同样是滚动容器**，也会白占槽位 ——
 *   客户端目录页的壳 `.shell.hc-cat-page .content` 正是 `overflow:hidden`（双栏容器），全局开会平白窄 8px。
 *   base.css 的 `.cat-tree` 早就踩过同一个坑（那里显式写 `scrollbar-gutter:auto` 关掉）。
 *   ⇒ 只给**会随内容变高的**滚动域开：详情整页（本条）+ 详情抽屉（下方 `.c-drawer.w-xl .c-drawer-body`）。
 * ⚠️ 旧浏览器忽略该属性 ⇒ 退化为旧行为（仍会抖），**不会**破坏布局。 */
.shell.hc-cdetail .content{padding-left:24px;padding-right:24px;scrollbar-gutter:stable}
/* 商品详情**抽屉**：与整页同档 1440（同样容纳 700 + 40 + 700）。
 * 背景：base.css 的 .c-drawer 默认 1000px（另有 .w800 购物车 / .w-lg 1200 采购模板），
 *   而「目录里点商品」打开的就是这个抽屉 —— 只改整页的话，从目录进仍然是窄版。
 * 窄屏由 base.css 的 `max-width:calc(100vw - 24px)` 兜底；≤1080 与其它档一致回退为 100vw。 */
.c-drawer.w-xl{width:1440px}
@media (max-width:1080px){ .c-drawer.w-xl{width:100vw} }
/* 抽屉侧的同一条修法（同一缺陷、同一机制）：抽屉壳是 `.hc-cat-page`，整页那条规则**命中不到它**。
 * 抽屉固定 1440 宽、内容盒更窄 ⇒ 8px 槽位的相对影响更大（实测图 657.5×657.5 ⇄ 661.5×661.5 @1460×1200）。
 * 🔴 选择器必须带 `.w-xl`：`.c-drawer-body` 被购物车（.w800）/ 采购模板（.w-lg）共用，
 *   而那两处的内容高度不随页签变化，开了槽位只会白占宽度。
 * 🔴 只在 `.c-drawer-body` 上开，**不碰** `.c-drawer` 本身：抽屉外框是 fixed 元素，不参与文档流滚动。 */
.c-drawer.w-xl .c-drawer-body{scrollbar-gutter:stable}
/* ===== 【2026-10-14 三改】右栏**不得参与左栏的行高计算** =====
 * 掌柜二次报障：「商品详情切换到规格参数，它会往底下跳。规格参数切换到适配配件，它也在跳……
 *   那 4 个页签的页头，这个位置都应该是固定不变呀？为什么它会上下来回跳？」
 * 🔴 根因（真机实测，商品 `xAP263407` = 32 条 SKU + info 1210 字；取证 `_assess/tmp/pd-tabs-move/`）：
 *   原版是 `grid-template-areas:"gallery buy" "tabs buy"` —— **购买栏跨两行**。
 *   跨行格子会把自己的高度**摊进它所跨的自动行**：购买栏被 `max-height:calc(100vh - …)` 顶到 ≈1041px，
 *   比「图集 588 + 页签区」还高 ⇒ **row1（图集行）被撑高** ⇒ 页签行被推下去；
 *   切到内容很长的「商品详情」⇒ row2 变高 ⇒ 不再需要撑 row1 ⇒ 页签行又抬回来。
 *   实测 `grid-template-rows`：detail `588px 15203.5px` ｜ spec `615.7px 403.3px` ｜ acc/sim `722.3px 296.7px`
 *   ⇒ **页签行 top 在四个页签间极差 134.3px**（762 / 789.7 / 896.3 / 896.3）。
 * 🔴 修法 = **把左列做成一个独立容器 `.pd-left`（图集 + 页签）**，右栏只是它的**兄弟列**；
 *   左列内部回到普通流 ⇒ 页签行 top = 图集高 + 22px，**与右栏无关、与页签内容也无关**。
 *   `.pd-cols` 因此退回**单行两列**（不再有 `grid-template-areas`）。
 * 🔴🔴 纪律：**跨行 / 跨列的 grid 项会把自身尺寸摊给所跨的自动行** —— 只要那个尺寸不由「本栏内容」决定
 *   （这里是 `max-height:100vh-…`），本栏的每一行都会变成它的函数。凡「一列里还有别的模块」时，
 *   别用跨行项，直接给该列一个自己的容器。
 * ⚠️ ≤900 单列的「图集 → 购买 → 页签」顺序**保持不变**：靠 `.pd-left{display:contents}` 让两个孩子
 *   重新成为网格项，再用显式 `grid-row` 排回原顺序（该档下视觉顺序 ≠ DOM 顺序，见下方媒体块注释）。 */
/* 两栏**等分**（各 700 @1440）。row-gap 只服务 ≤900 单列档（两列档下页签在 .pd-left 内部，间距走它的 margin-top）。 */
.pd-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:40px;row-gap:22px;align-items:start}
/* 左列：图集 + 页签。**它自己的高度只由自己的内容决定** —— 这是「页签行不动」的结构前提。 */
/* 🔴🔴 【2026-10-14 四改】左列必须有**最小高度** —— 这是 sticky 的「行程」来源。
 *   掌柜第三次报障（条件说得很准）：「规格只有 3、4 个、规格列表里没有下拉框时，怎么切都不抖；
 *     当规格列表太多、**里面出现上下下拉框**时，再来回切页签，右侧就上下抖动。」
 *   🔴 根因：`position:sticky` 的位移受**包含块**（`.pd-cols` 的行高）限制 ⇒ 可吸附行程 = 行高 − 白卡高。
 *     白卡被 `max-height` 顶到 ≈ 整屏高（规格多 ⇒ 内部出现滚动条，即掌柜说的那个条件），
 *     而短页签（适配配件 / 相似推荐）的左列内容**比白卡矮** ⇒ 行高 = 白卡高 ⇒ **行程 = 0**
 *     ⇒ 白卡完全丧失吸附能力、退化成普通元素随页面滚；切到长页签行程突然暴增又贴回顶部
 *     ⇒ 右侧模块上下跳。三视口实测**白卡视口 y 极差 80.00px**（detail 94 ⇄ acc/sim 14），
 *     而同期页签行极差 0.00px（所以掌柜看到的是「只有右侧在抖」）。取证 `_assess/tmp/pd-jit2/`。
 *   ⇒ 给左列一个 ≥ 白卡高 + 200px 的最小高度：短页签也有行程、也贴顶 ⇒ 与长页签**完全一致**。
 *   ⚠️ 只在「左列自然高度比它矮」时生效（即短页签）；长页签的自然高度早就超过它，不受影响。
 *   ⚠️ ≤900 单列档下 `.pd-left{display:contents}` 不生成盒子 ⇒ 本条自动失效（单列本就不 sticky）。 */
.pd-left{min-width:0;min-height:calc(100vh - var(--vh-chrome-pd) + 200px)}
.pd-left .pd-tabs{margin-top:22px}
/* 左栏：图集（竖排缩略图 + 大图） */
.pd-gallery{display:flex;gap:14px;align-items:flex-start;min-width:0}
.pd-rail{flex:0 0 72px;display:flex;flex-direction:column;gap:10px}
.pd-hero{flex:1 1 auto;min-width:0}
/* base.css:1134 的 `.shell.hc-c .prod-img`（0,3,0）会压掉普通选择器 —— 这里用 `.pd-cols .pd-gallery .prod-img`
 * 提到**同特异度**，且 pages.css 在 base.css 之后加载 ⇒ 后者胜出。
 * 🔴 刻意**不带** `.hc-cdetail` 作用域：抽屉的壳是 `.hc-cat-page`，带作用域会让抽屉里的图停留在
 *   base.css 的 350px（实测：左栏 668 却只显示 350 的图，右侧大片空白）。
 * 左栏 700 减去缩略图栏 72 与间距 14 ⇒ 大图可用 614，**铺满**即可。 */
.pd-cols .pd-gallery .prod-img{width:100%;height:auto;aspect-ratio:1/1;max-width:100%}
.gal-th{width:72px;height:72px;padding:0;border:1px solid var(--line);border-radius:10px;
  background:var(--canvas);overflow:hidden;cursor:pointer;transition:border-color .15s,box-shadow .15s}
.gal-th:hover{border-color:var(--pri)}
.gal-th.on{border-color:var(--pri);box-shadow:0 0 0 2px var(--pri-weak)}
.gal-th img{width:100%;height:100%;object-fit:contain}
.pd-tabs{min-width:0}
/* ---------- 右栏：常驻吸顶（头 / 尾固定 · 中段内部滚动）----------
 * 🔴 为什么中段必须内部滚动：SKU 可达 100+ 条。整列高于视口时，sticky 会让列底
 *   （含「批量加入购物车」按钮）**永远留在视口之外** —— 滚不到也点不着，这是真缺陷，不是审美。
 *   三行结构（head / body / foot）= 标题价格钉在顶、按钮钉在底、规格列表自己滚。
 * 🔴 上限必须**扣掉 .content 的顶部内边距（30px）与 sticky 的 top（8px）**：
 *   sticky 的 top 偏移在带内边距的滚动域里是「内边距之外再加」的（Edge/CDP 实测 top = 30 + 8 = 38），
 *   只写 100vh-24 会让列底连同底部按钮一起被推出视口（实测超出 14px）。
 * 🔴🔴 2026-10-14 四改：**余量 64px 不足，已提到 160px**。它不是「安全边界」那种可以随便取的值，
 *   而是一条**硬条件**（三视口实测同一套数：1460×1200 / 1920×1080 / 1440×900）：
 *     · 白卡贴顶后顶部落在视口 **y = 94**（恒定，与视口高无关）⇒ 可用高度 = `100vh − 94`
 *     · 白卡上方内容 = 130px；`.content` 底部余量 = 50px；「已滚动 ⇒ 贴顶」的收益 = 36px
 *     · 要让短页签（左列比白卡矮）下白卡**仍然贴顶**，必须 `白卡高 ≤ 100vh − 130 − 50 + 36`
 *       ⇒ **扣减量 ≥ 144px**。取 160 留 16px 余量。
 *   不足的后果不是「难看」，而是**白卡顶不动**：短页签下行高 = 白卡高 ⇒ sticky 行程 = 0 ⇒
 *   白卡退化成普通元素随页面滚，切页签时与长页签（贴顶）差 80px —— 掌柜报的「右侧上下抖」。
 *   取证 `_assess/tmp/pd-jit2/`；配套的左列 `min-height` 见 `.pd-left`。 */
/* ===== 【2026-10-14 右栏分区块】打破「一锅炖」文字墙：整栏一张白卡 + 五个功能区 =====
 * 结构：① 身份 .page-head → ② 价格 .price-line（原「单价」小标题已于 2026-10-14 按掌柜指令删除，
 *   分隔发丝线保留并改挂在 .price-line 上）→ ③ 选项（多规格 .pd-blk-spec /
 *   单规格「采购数量」块 + 部门块，全在 .pd-buy-body 滚动域）→ ④ 合计 #pd-sum → ⑤ 按钮 .pd-acts。
 * 🔴 白卡**直接写在 .pd-buy 上**，不给它挂 `.card`：`.shell.hc-c .card{padding:24px}`(0,2,0) 会
 *   压死下面 ≤1240 块里 `.pd-buy{padding:16px 12px}`(0,1,0) ⇒ 窄栏收缩内距将无法实现。
 *   用 `box-shadow:var(--sh1)`（=1px --line 发丝环）而非 border：与 .card 同源且**不占布局**。
 * 🔴 `.pd-buy-body` 的 `padding` 必须保持以 `0 ` 开头（test/cdrawer-smoke.js 钉住）
 *   ⇒ 区块竖距一律用**子元素 margin** 承担，绝不写 .pd-buy-body{padding-top}。 */
/* 🔴 只占**第 2 列第 1 行**（不再 `grid-area:buy` 跨两行）—— 跨行会把 `max-height:100vh-…` 的
 *   高度摊进左列的行里，页签行就会被推着走（详见 `.pd-cols` 上方那段）。 */
.pd-buy{grid-column:2;grid-row:1;position:sticky;top:8px;align-self:start;
  display:flex;flex-direction:column;max-height:calc(100vh - var(--vh-chrome-pd));min-height:0;
  background:var(--canvas);box-shadow:var(--sh1);border-radius:var(--r-lg);padding:24px}
.pd-buy-head{flex:0 0 auto}
/* 区块小标题：与既有 .pd-sku-list-h 同档（12px/--t4），保证一栏里「区块标题」只有一套语法 */
.pd-blk-h{font-size:12px;color:var(--t4)}
/* head 内「身份 ↔ 价格」的分隔：加粗留白 + 一条 --line3 发丝线。**已从「单价」小标题移到价格行上**：
 * 【2026-10-14 掌柜指令】删掉「单价」那两个字（「我看 1688、京东、淘宝，价格上面都没有标单价这两个字」）——
 * 🔴 保留的是**分隔**本身（区隔身份与价格），不是那两个字；`border-top` 因此挂到 `.price-line`。
 * 🔴 配套纪律：`.price-line` 上**不得再写内联 `margin-top`** —— 内联会盖掉这里的 `margin-top:14px`，
 *   发丝线上移、间距缩水且**无任何报错**（`pdbuy-blocks-smoke` 有专门判据 + 变异自证）。 */
.pd-buy-head .price-line{margin-top:14px;padding-top:14px;border-top:1px solid var(--line3)}
.pd-buy-body .pd-blk-h{margin-bottom:8px}
/* 选项区（.pd-buy-body）内区块间距：只写在子元素上（body 的 padding-top 恒为 0）。
 * 2026-10-14 二改后 body 里通常只剩一个区块（多规格 `.pd-blk-spec` / 单规格「采购数量」）——
 * 「所属部门」已**移出** body（见下方 `.pd-buy-dept` 段）。本行留作 body 再加区块时的间距契约。 */
.pd-buy-body .pd-blk + .pd-blk{margin-top:18px}
.pd-buy-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;margin-top:14px;padding:0 4px 6px 2px;scrollbar-width:thin}
/* ===== 【2026-10-14 掌柜指令】「所属部门」= 独立模块，规格列表滚动不得带动它 =====
 * 🔴 位置：`.pd-buy-body`（**唯一滚动域**）之**外**的兄弟段 ⇒ 右栏现为 head / body / dept / foot 四段。
 *   它原先作为一个 `.pd-blk` 与规格块同处 body 内，而 body 就是滚动域
 *   ⇒ 拖规格列表会把部门一起滚走（掌柜报障：「规格列表上下拖动拉动不能影响这个所属部门这个模块」）。
 *   `flex:0 0 auto` ⇒ 本段**永不参与滚动**；规格再多也只压缩 body 的可用高度（body 有 min-height:0）。
 * 🔴 分隔语法：与 head / foot 同一条 `--line3` 发丝线 —— 本栏「区块分隔」只有这一套语法；
 *   刻意**不套 `.card`**：那会变成「白卡里套白卡」（同 2026-10-14 去掉 `.sp-pick-card` 的那一刀）。
 * 🔴 配色/排版零改动：`.dept-mod` / `.dp-pick` 整组样式仍在 base.css（全局，弹窗内外共用）。 */
.pd-buy-dept{flex:0 0 auto;margin-top:14px;padding-top:14px;border-top:1px solid var(--line3)}
/* `.dept-mod` 自带 margin-top:12px（base.css）⇒ 会与上面的 padding-top 叠成 26px，本栏作用域内清零 */
.pd-buy-dept .dept-mod{margin-top:0}
/* 部门可能很多：`.dp-pick-list` 的全局上限 46vh 是**弹窗口径**，在右栏偏大 —— 任它自由撑高，
 *   head + dept + foot 三段的固定高会把 body 压到 0 并顶破 `.pd-buy` 的 max-height。
 *   本栏给 3 行上限：3×37（`.dp-pick` 实测高 = 9×2 内距 + 1.2×14 行高 + 1×2 描边）+ 2×8（gap）= 127px。
 *   超出时**本列表自己滚** —— 三个滚动域（规格 / 部门 / 整列）互不牵动。 */
.pd-buy-dept .dp-pick-list{max-height:127px}
/* padding-top 必须为 0（表头已按掌柜指令删除，此条**仍然保留**）：它原来的理由之一是
 *   「表头吸顶时若留内边距会浮出卡片顶边、露一条白边」——那个理由随表头消失，
 *   但 0 依然是更紧的取值：规格卡直接贴齐滚动域顶边，不留无意义空白。
 *   将来任何「内容吸顶到卡片顶边」的做法都依赖这一条。 */
.pd-buy-foot{flex:0 0 auto;margin-top:14px;padding-top:14px;border-top:1px solid var(--line3)}
.pd-buy #dl-addbtn{width:100%}
/* ===== 【2026-10-13 立即下单】详情页底部：左【立即下单】/ 右【加入购物车】 =====
 * 单规格 → 数量行 + 按钮行（.pd-buy-line 用 flex，窄屏自动折行，无需新增 @media）；
 * 多规格 → 合计行 + 按钮行。
 * 🔴 加购按钮（#dl-addbtn）已于 **2026-10-14 成套改造**（白底橙描边方角），见下方「加购按钮皮」；
 *   两颗按钮现在同高 / 同宽 / 同 4px 圆角。 */
.pd-buy-line{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px}
/* 【2026-10-14】三枚并排：立即下单 / 加购物车 / 收藏。前两枚等分（主行动），
 *   收藏为 `auto` —— 宽度按内容走（图标 + 两字），是低频次要动作，不参与等分，
 *   这样窄栏 340px 下两枚主按钮仍等宽。 */
.pd-acts{flex:1 1 240px;display:grid;grid-template-columns:1fr 1fr auto;gap:12px}
.pd-acts .btn{width:100%;padding:0 12px}
/* --- 立即下单按钮皮（2026-10-13：掌柜给定参考图，逐像素实测落地）-----------------
 * 🔴 下面每个值都来自参考图的**像素实测**，不是目测：
 *   · 渐变方向 = 纯横向：同一 x 的上下两点**逐字节同色**（#FF702D/#FF702D）⇒ 90deg，不是对角。
 *   · 两端色：#FF702D（左）→ #FF4400（右）。R 恒 255；G 112→68、B 45→0 均为线性。
 *   · 前 12% 是**平坦段**（x=16→48 恒 #FF702D，263px 宽里占 32px）⇒ 首停靠点写 13%，
 *     CSS 会把首个停靠点向前填充，正好得到该平坦段（写 0% 会丢掉它）。
 *   · 圆角：按圆弧模型逐行拟合（r=2/3/4/5… 比累计偏差）**r≈3px**（按钮高 43px）；
 *     落地取 4px —— 本仓最小圆角档，差 1px 在这个尺寸下不可辨。
 *   · 无阴影、无描边；文字纯白，粗体（`.btn` 已是 font-weight:700，无需覆写）。
 * 🔴 色值定义为**本端令牌**再被规则引用（同 base.css 的 --pri-action / --pri-action-press 体例），
 *   不把字面量写进规则体。按压态取该体例的比例 ×0.91（#FFD02F→#E8BC20 即此比例）。
 * 🔴 2026-10-14 成套改造后，加购按钮（#dl-addbtn）已另出皮（白底 + 1px 橙描边 + 橙字 + 4px 方角），
 *   见下方紧接的「加购按钮皮」段 —— 两枚现为「橙渐变实心 / 白底橙描边」的同形对。 */
.shell.hc-c{--buy-g1:#FF702D;--buy-g2:#FF4400;--buy-g1-press:#E86629;--buy-g2-press:#E83E00}
.shell.hc-c .btn.buy{background:linear-gradient(90deg,var(--buy-g1) 13%,var(--buy-g2) 100%);color:#fff;border-radius:4px}
.shell.hc-c .btn.buy:hover{background:linear-gradient(90deg,var(--buy-g1-press) 13%,var(--buy-g2-press) 100%)}

/* --- 加购按钮皮（2026-10-14 成套改：白底 + 1px 橙描边 + 橙字 + 4px 方角，仅详情页 .pd-acts 内）---
 * 参考图逐像素实测：内部底色 #FFFFFF / 四边描边 1px 均 #FF4000 / 文字色众数 #FF4000 / 与左钮同 4px 方角。
 * 🔴 作用域锁死在详情页那一对：.pd-acts 仅 detail.js 产出（目录页的详情抽屉复用同一段 innerHtml，同吃新皮）；
 *   客户端其余 .btn.pri（提交订单 / 弹窗确认 / 登录 / 企业中心 / 模板）一律不动。
 * 🔴 必须用 #dl-addbtn（(1,1,0)）：class 方案 `.pd-acts .btn.pri`(0,3,0) 会**输给** base 的
 *   `.shell.hc-c .btn.pri:hover`(0,5,0) ⇒ 黄底 --pri-action-press 会真的透出来。
 * 🔴 令牌**另起一块**，不并入上一行 —— 并进去会使 test/buynow-smoke.js 的「删令牌」变异锚点失配。
 * 🔴 1px 描边不会改变 42px 高度（base.css:79 是 `*{box-sizing:border-box}`）⇒ 与左钮天然同高，无需改 padding。 */
.shell.hc-c{--buy-line:#FF4000;--buy-line-weak:#FFF0EB}
.pd-acts #dl-addbtn{background:#fff;border:1px solid var(--buy-line);color:var(--buy-line);border-radius:4px}
.pd-acts #dl-addbtn:hover{background:var(--buy-line-weak);border-color:var(--buy-line);color:var(--buy-line)}
/* id 规则 (1,1,0) 会静默压过 base.css:1103 的 `.shell.hc-c .btn:disabled`(0,4,0) ⇒ 必须复述禁用灰 */
.pd-acts #dl-addbtn:disabled{background:var(--line3);border-color:transparent;color:var(--t5)}

/* --- 【2026-10-14 掌柜指令】加购**右侧**的【收藏】按钮（图标 + 文字两态）------------------
 * 🔴 披的是 `.btn.ghost`，而 base.css:1099 的 `.shell.hc-c .btn.ghost`(0,4,0) 是**透明底 + 品牌蓝描边 + 蓝字**
 *   ⇒ 必须用 id（(1,1,0)）显式接管成**中性灰**：收藏是第三顺位动作，不能与橙色的两枚主按钮抢眼。
 * 🔴 `border-radius:4px` 必须显式写 —— 缺了它 `.shell.hc-c .btn` 的 999px 胶囊会静默接管，
 *   三枚形状就不成套了（同 #dl-addbtn 的踩坑记录）。
 * 🔴 已收藏态 `.on` 借橙色令牌（`--buy-line` 一族）表达「已加入」；图标是**实心/描边同一枚路径**
 *   两态（favSvg 的既有约定），换态时只换 fill，不换图形。 */
.pd-acts #dl-favbtn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:0 12px;background:var(--canvas);border:1px solid var(--line2);color:var(--t2);border-radius:4px}
.pd-acts #dl-favbtn:hover{background:var(--sf);border-color:var(--line3);color:var(--t1)}
.pd-acts #dl-favbtn.on{background:var(--buy-line-weak);border-color:var(--buy-line);color:var(--buy-line)}
/* 图标槽位：15px 视觉尺寸（与 .btn 14px 文字同高），`display:block` 消掉 svg 的基线缝隙 */
.pd-acts .pd-fav-ic{display:inline-flex;width:15px;height:15px;flex:0 0 auto}
.pd-acts .pd-fav-ic svg{width:100%;height:100%;display:block}

/* ===== 【2026-10-14 掌柜定稿】加购弹窗「骨架分明」：选项 / 价格 / 按钮三段 =====
 * 掌柜原话：「价格归价格，选项归选项，按钮归按钮。用留白隔开它们，用字号和颜色区分主次。这就是骨架分明。」
 * 三点定稿（掌柜当日选择）：① 段序 = 金额在上、部门在下（**保持原位置**，不重排 DOM）
 *                        ② 页头仍用一行标题（不做商品小卡）　③ 金额 20px / 600 / 价格红
 * ⇒ 本轮**全是「量」的改动**：留白档位、字号字色、两条边界线。零结构变更、零类名变更。
 * 🔴 三条规则（下面每个取值都由它们推出，不是随手调的）：
 *   ① **留白只有三档**：块内 8 / 12、块间 **20**、页脚 16。旧版是「到处 12px」⇒ 三段视觉上连成一片。
 *   ② **主次靠字号 + 字色**：全弹窗唯一最大字号 = 金额（20/600/价格红）；行内单价从 15/600/--t1
 *      降到 **14/500/--t2**，把「主」让给金额；说明性文字一律 12/--t4。
 *   ③ **边界线只出现在「滚动域」与「按钮区」**：规格列表上下各一条 ⇒ 一眼看出「只有中间会滚」；
 *      页脚上一条 ⇒ 按钮从内容里被「切」出来。
 * 🔴 作用域：`.pk-*` 只在本弹窗出现，值就地改；但 `.dept-mod` 与 `.mf` 是**共用件**
 *   （详情页也用 dept-mod、站内所有弹窗都用 .mf）⇒ 这两条必须带 `.modal.pk-modal` 限定。 */
/* ① 段间留白统一 20px（原：列表上沿 4 / 摘要上沿 12 / 部门自带 12）
 *   ⚠️ 选择器自身的下边距在下方 `.pk-dim-bar`（已归零）—— 两处不相加，间距只由本条承担。 */
.pk-scroll{max-height:46vh;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  margin:20px 0 0;padding:4px 4px 4px 2px;scrollbar-width:thin;
  border-top:1px solid var(--line3);border-bottom:1px solid var(--line3)}
.pk-list{display:flex;flex-direction:column}
.pk-row{display:flex;align-items:center;gap:12px;padding:9px 10px;border-top:1px solid var(--line3);
  border-radius:10px;transition:background .15s}
.pk-row:first-child{border-top:0}
.pk-row:hover{background:var(--sf2)}
/* 「已填数量」的行：淡蓝底 + 左侧色条（inset 阴影而非 border-left —— 后者会撑开行宽、把价格与步进推歪） */
.pk-row.sel{background:var(--pri-weak);box-shadow:inset 3px 0 0 var(--pri)}
.pk-row.hide{display:none}   /* 维度筛掉（不删行、不动数据，已填数量因此天然保留） */
.pk-th{flex:0 0 auto;width:44px;height:44px;border:1px solid var(--line);border-radius:8px;
  background:var(--canvas);overflow:hidden;display:flex;align-items:center;justify-content:center}
.pk-th img{width:100%;height:100%;object-fit:contain}
.pk-main{flex:1 1 auto;min-width:0}
.pk-lb{font-size:15px;font-weight:600;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 【掌柜定稿】行内单价**降为次要**：原 15/600/--t1 与规格名同级 ⇒ 价格与选项抢主次。
 * 现 14/500/--t2，把「主」让给下方的金额（全弹窗唯一最大字号）。 */
.pk-price{flex:0 0 auto;min-width:72px;text-align:right;font-size:14px;font-weight:500;
  color:var(--t2);font-variant-numeric:tabular-nums;white-space:nowrap}
/* 步进宽度：详情页取 `--pd-step-w`（定义在 .pd-cols 上，弹窗里取不到）⇒ 本处独立声明同一数值。
 * 🔴 该数值 = base.css 的客户端步进几何现算值（cdrawer-smoke 有跨文件对拍），改 base 时要同步。 */
.pk-step{flex:0 0 102px}
/* ② 价格段：件数 12/--t4（数字 --t2）在左，金额 20/600/价格红在右 */
.pk-sum{display:flex;align-items:baseline;gap:8px;margin-top:20px;font-size:12px;color:var(--t4)}
.pk-sum.on{color:var(--t3)}
.pk-sum .pk-sum-n b{color:var(--t2)}
.pk-sum .pk-sum-t{margin-left:auto;font-size:20px;font-weight:600;color:var(--promo);letter-spacing:-.4px}
/* 🔴 下面两条必须带 `.modal.pk-modal` 限定：`.dept-mod` / `.mf` 都是**共用件** */
.modal.pk-modal .dept-mod{margin-top:20px}
.modal.pk-modal .mf{margin-top:20px;padding-top:16px;border-top:1px solid var(--line3)}
/* 维度选择器：逐值镜像详情页 .pd-dim-*（同一套瓦片：图在上、标签两行、选中描边内缩）。
 * ⚠️ 下边距已归零（原 6px）—— 与列表的间距由 `.pk-scroll` 的 20px 单独承担，避免两处相加。 */
.pk-dim-bar{margin:2px 0 0}
/* 规格区标题（2026-10-14 掌柜指令「这个模块上面增加 选择规格 这四个字」）
 * 与详情页 `.pd-sku-list-h` **同档**：12px / `--t4`（同一栏里「区块标题」只留一套语法）。
 * 🔴 位置在 `.pk-scroll` **之外** —— 它标的正是「滚动域」这个块，自己就不能跟着滚
 *   （标题滚走 ⇒ 滚到中段就不知道这一列是什么，与「摘要/部门/按钮钉住」同一条纪律）。
 * 间距沿用三档口径：与上方块 20（块间）、与列表 8（块内）。
 * ⚠️ 只在「标题存在时」收紧列表上沿 ⇒ 仅多规格渲染标题（单规格无可选，与详情页口径一致），
 *   单规格时列表仍吃 `.pk-scroll` 自带的 20px，不会贴到弹窗顶部。 */
.pk-list-h{margin-top:20px;font-size:12px;color:var(--t4)}
.pk-list-h + .pk-scroll{margin-top:8px}
.pk-dim-h{display:flex;align-items:baseline;gap:8px;margin-bottom:8px}
.pk-dim-name{font-size:12.5px;color:var(--t4)}
.pk-dim-cur{font-size:12.5px;font-weight:600;color:var(--t1)}
/* 🔴 【2026-10-24】与详情页 `.pd-dim-*` **同一套视觉参数**（掌柜「购物车/结算里的包装选择器要一起统一」）：
 *   固定 7 列、缩略图 68px、瓦片宽度上限 96px、标签 2.5em —— 两套类名必须分开（共用 `.pd-*` 会被
 *   全局选择器消费 ⇒ 弹窗与详情抽屉同时存在时串号，见 cart-view.js 那段说明），但**尺寸逐值相等**。
 *   `test/pkadd-smoke.js` 的 ⑥ 组会把两边的高度/字号**对拍**，只改一处即报红。
 *   ⚠️ 唯一刻意不同的是 `max-height`：这里是 **226px（两行）**，详情页是 341px（三行）。
 *   原因很实际 —— 本弹窗的纵向空间要留给「规格列表（.pk-scroll 46vh）+ 包装 + 摘要 + 部门 + 页脚」，
 *   实测弹窗总高 528px（两行）/ 669px（≤560 视口、5 列）；放到三行会把规格列表挤到几乎看不见。
 *   代价：15 个取值以上要网格内滚（详情页是主战场，弹窗是临时填数量）。
 *   弹窗宽 = min(760px,100vw)，712px 网格下 7 列 = **94px**（改前 auto-fill 排 9 列、7 个取值右边空 159px）。 */
.pk-dim-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;
  max-height:226px;overflow-y:auto;padding:2px 4px 2px 2px;scrollbar-width:thin}
.pk-dim-opt{display:flex;flex-direction:column;align-items:center;gap:2px;padding:3px 4px;max-width:96px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--canvas);cursor:pointer;
  font-family:inherit;transition:border-color .15s,background .15s}
.pk-dim-opt:hover{border-color:var(--pri)}
.pk-dim-opt.on{border-color:var(--pri);background:var(--pri-weak);box-shadow:inset 0 0 0 1px var(--pri)}
.pk-dim-th{display:flex;align-items:center;justify-content:center;width:100%;height:68px;overflow:hidden}
.pk-dim-th img{width:100%;height:100%;object-fit:contain}
.pk-dim-lb{width:100%;height:2.5em;overflow:hidden;overflow-wrap:anywhere;text-align:center;
  font-size:11.5px;line-height:1.25;color:var(--t1)}

/* ===== 【2026-10-13 立即下单】订单确认页（路由 c-checkout）=====
 * 行用 flex + wrap（窄屏「操作」自动换行），**刻意不新增 @media** —— 断点档位受
 * test/responsive-breakpoint-smoke.js 白名单约束。 */
.ck-wrap{display:flex;flex-direction:column;gap:16px}
.ck-card .card-title .opt,.submit-card .card-title .opt{color:var(--t3);font-weight:400}
.ck-list{display:flex;flex-direction:column;margin-top:10px}
.ck-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding:12px 0;border-bottom:1px solid var(--line3)}
.ck-row:last-child{border-bottom:none}
.ck-th{flex:0 0 56px;width:56px;height:56px;border-radius:10px;overflow:hidden;background:var(--sf);display:flex;align-items:center;justify-content:center}
.ck-th img{width:100%;height:100%;object-fit:cover}
.ck-noimg{font-size:18px;font-weight:600;color:var(--t4)}
.ck-main{flex:1 1 200px;min-width:0}
.ck-n{font-size:14px;font-weight:600;color:var(--ink);line-height:1.4}
.ck-meta{font-size:12px;color:var(--t3);margin-top:4px}
.ck-dept{font-size:12px;color:var(--pri-600);margin-top:4px}
.ck-price{flex:0 0 auto;font-size:13px;color:var(--t2);white-space:nowrap}
.ck-step{flex:0 0 auto}
.ck-sub{flex:0 0 76px;text-align:right;font-size:14px;font-weight:600;color:var(--ink)}
.ck-ops{flex:0 0 auto;display:flex;gap:10px;white-space:nowrap}
.ck-foot{display:flex;align-items:baseline;gap:10px;margin-top:12px;padding:16px 0 0;border-top:1px solid var(--line3)}
.ck-foot .cf-lb{margin-left:auto;font-size:12px;color:var(--t3);font-weight:600}
.ck-foot .cf-amt{font-size:18px;font-weight:600;color:var(--ink)}
.ck-foot .cf-cnt{font-size:12px;color:var(--t4)}
.ck-empty{padding:48px 20px;text-align:center}
.ck-empty-t{font-size:18px;font-weight:600;color:var(--ink)}
.ck-empty-d{margin-top:8px;font-size:13px;line-height:1.7;color:var(--t3)}
.ck-empty-a{margin-top:16px;display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
/* 抽屉自身已是滚动域（.c-drawer-body，padding 24 + 约 71px 头部）⇒ 上限还要再扣这一截，
 * 否则列高超出抽屉可视区，底部按钮同样会被推出视野。 */
.c-drawer-body .pd-buy{max-height:calc(100vh - var(--vh-chrome-pd-drawer))}
/* 抽屉内的色块网格：原有一条把上限压到 160px 的抽屉覆盖，2026-10-11 掌柜指令后**已删除** ——
 * 那条会让抽屉里 16 色排不满两行（实测网格内滚 26px），与「两行时不依赖下拉」直接冲突。
 * 现在整页与抽屉**共用基类的 186px**（= 两行自然高的实测值），只有一个口径。 */
/* 【2026-10-11 掌柜指令 · 该行容器已整条删除，本段规则全部下线】
 * 原这里有一条「计数条」行（一行 flex），先后装过三样东西，被掌柜**逐次点选删除**：
 *   ① 关键词筛选输入框 → 删（同日）；② 「显示 x / N 条」计数 → 删（同日，见 detail.js 说明）；
 *   ③ 「清空数量」链接 → 删（同日）。三样都没了 ⇒ 容器本身也不再渲染，规则一并移除。
 * 🔴 顺带**兑现了 25.2px 高度**（行高 19.2 + margin-top 6）—— 这 25px 已并入色块网格的高度预算。
 * 🔴 归零的**替代路径**：规格行内数量框直接输 0 / 用行内「−」减到 0（步进的下限本就是 0）。
 *   「一次清空全部」目前**没有入口**（掌柜已知悉）；若日后要加回，落点需重新选，不要复活这一行。 */
/* ===== 【2026-10-14 掌柜指令】订单详情：「客户与交付信息 ＋ 收货二维码」**一行两栏** =====
 * 掌柜原话：「把收货二维码放在客户预交付信息的右侧，采用一行两栏布局」。
 * 版式与商家端一致（`merchant/styles/pages.css` 的 `.shell.hc-m.hc-mord .ord-two`，2026-10-12 掌柜指令）：
 *   左 = 客户与交付信息（kv 行多 ⇒ 给略宽的 1.15fr）· 右 = 收货二维码。
 * 🔴 两处 margin 必须**成对**处理，漏一处就歪：
 *   ① `.shell.hc-c .card + .card{margin-top:18px}`（base.css）在 grid 里是**同级兄弟** ⇒ 不抵消
 *      右卡会被整体下推 18px、两栏顶边不齐（商家端踩过同一个坑）。
 *   ② 反方向：紧随其后的「订单条目明细」卡的**前一个兄弟已变成 `.ord-two`**，`.card + .card`
 *      不再命中 ⇒ 那张卡会紧贴双栏、丢掉 18px 间距。故补 `.ord-two + .card`。
 * 🔴 作用域带 `.shell.hc-c`：`ord-two` 这个类名客户端与商家端都在用（各自壳不同），裸写会与商家端
 *   那条规则互相打架（谁后加载谁赢，而两端 CSS 的加载序不同）。
 * 🔴 已作废单（CLOSED）不出二维码卡 ⇒ `orders.js` 里**不套双栏容器**（否则信息卡只占半边、右半留白）。
 * 🔴 ≤1080 降级单栏：两栏并排会把 kv 的值挤到折行，竖排更好读。档位取 1080（本仓 4 档之一，
 *   受 test/responsive-breakpoint-smoke.js 白名单约束，**不得自造断点**）。
 * 🆕【2026-10-14 掌柜第二道指令】「左右两个模块就是要上下对齐，你这一边高一边低，太丑了」。
 *   🔴 病根 = `align-items:start`（从商家端照抄来的那一行）：它让两卡各按**自身内容**定高 ⇒
 *     顶边齐、**底边差 80px**（实测左 236 / 右 316）。
 *   🔴 修法 = **去掉 `align-items:start`**，用 grid 默认的 `stretch` ⇒ 两卡拉成**同一行高**，
 *     顶边与底边**同时**对齐。⚠️ 不要改成 `align-items:center`（那是让矮卡居中，仍不等高）。
 *     同一现象在商家端也存在，但那边左栏 kv 行远多于右栏（卡高于二维码卡），观感相反 —— **本轮不动商家端**。
 * 🆕 同批：左栏「客户与交付信息」的**信息字号适当放大**（掌柜要求）。
 *   基线 = 客户端 `.shell.hc-c .kv .k/.v` 的 12px / 13px（base.css:1122-1123）。
 *   只放**值**：13 → **15px**；标签维持 12px —— 标签列宽固定 96px，放大会让「企业 / 联系人」折行。
 *   🔴 刻意**不加 `font-weight:500`**：Windows 雅黑只有 400/700，500 会**静默失效**（本仓红线）。
 *   行距 10 → 12px，既好读也把左卡高度往右卡那侧补一点。 */
.shell.hc-c .ord-two{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:16px}
.shell.hc-c .ord-two > .card{margin-top:0}
.shell.hc-c .ord-two + .card{margin-top:18px}
.shell.hc-c .ord-two .kv{margin-bottom:12px}
.shell.hc-c .ord-two .kv .v{font-size:15px}
@media (max-width:1080px){
  .shell.hc-c .ord-two{grid-template-columns:minmax(0,1fr)}
}
/* ===== 【2026-10-14 掌柜指令】订单详情商品行**整行可点** → 右侧滑出商品详情 =====
 * 与「商品目录行」「购物车明细行」**同一套**（动作都是 `cd-open`，抽屉本体都是 detail.js 的
 *   `cDetailDrawerHtml()`）；本行纯只读、**没有输入框**，故不需要购物车那套 row-hold 阻断位。
 * 🔴 选择器用 `[data-act="cd-open"]` 而**不是** `.ov-tbl tbody tr`，两个理由：
 *   ① `.ov-tbl` 是共用类（**商家端**订单表也是 `cart-tbl ov-tbl`，见 base.css §cart-tbl）——
 *      `.shell.hc-c` 已把商家端挡在门外，但「只有能点的行才给手型」本身就是更准的判据；
 *   ② 商品**已移出本企业可见范围**的行不挂动作（挂了点了只会 toast「商品不存在」）⇒ 它们不该变手型，
 *      用属性选行天然把这类行排除掉。序号 / 合计行等同理，一条都不误伤。 */
.shell.hc-c .ov-tbl tbody tr[data-act="cd-open"]{cursor:pointer}
/* ---------- 多维规格：维度选择器（2026-10-11） ----------
 * 真实数据（一号通 offerId 948758529673）：封面颜色 16 值 × 规格 11 值，但满组合 176 实际只有 **36 条**
 *   SKU —— 组合是**稀疏**的（选一个颜色后可选规格在 1~8 条之间波动）。故这里做成「缩略图瓦片 +
 *   单选导航」，下方列表只显示该颜色的规格行（不筛的话用户找不到、也看不出这色只剩几档）。
 * 🔴 缩略图高度**固定 40px**，不按列宽撑成正方形 —— 4 列时方图会有 ~155px，16 个颜色就是 620px 高。
 *   网格用 auto-fill：**实测**整页右栏 672px ⇒ 网格内宽 608px，`minmax(64px,1fr)` 得 8 列（瓦片 69px）
 *   ⇒ 16 个值正好 2 行。⚠️ 早先写的 `minmax(72px,1fr)` 在 608px 下只排得下 **7** 列，
 *   16 色变 **3 行**（实测 gridTemplateRows 三条轨）—— 既多占 40px 又要网格内滚动。
 *   64px 是实测反推的下限（8×64+7×8=568 ≤ 608）；再小则「复古绿-方形本」这类 7 字标签会溢出两行框。
 *   抽屉（668）同档；窄屏自动减列。
 * 🔴🔴 【2026-10-24 掌柜「这个模块设计为一排7个，每个卡片适当左右拉宽点」】
 *   **固定 `repeat(7,minmax(0,1fr))`，不再用 auto-fill。** 原因很具体：本商品（封面颜色 7 个值）
 *   在 auto-fill 下排了 **8 列**，7 个瓦片只占 7 格、**右侧空出一整格 76px**，
 *   每个瓦片被压到 **68px**（实测网格内宽 606px）。改固定 7 列后：瓦片 **79px**（+11px / +16%）、
 *   右侧空隙 **0**、仍是一行 —— 这正是掌柜要的「一排 7 个、卡片拉宽」。
 *   实测各档（视口 → 网格内宽 → 瓦片宽）：
 *     1440 → 618 → 81 ｜ 1400 → 598 → 78 ｜ 1300 → 548 → 71   （>1240 都是 7 列 / 一行）
 *     1240 → 360 → 83 ｜ 1200 → 348 → 79 ｜ 1100 → 315 → 71 ｜ 1000 → 300 → 68 （**降 4 列**，见下）
 *     900 → 790 → 96 ｜ 800 → 690 → 91 ｜ 760 → 650 → 85      （单列全宽，7 列）
 *     560 及以下 → 4 列（手机，见文件末尾那个断点块）
 *   🔴 **901–1240 必须降 4 列**：该档虽是两列布局，但右栏被 `clamp(340px,32.3vw,400px)` 收到
 *     340–400px（实测网格内宽仅 300–370px），7 列在那里只剩 37–45px —— 连 56px 缩略图都被压，
 *     比原来 auto-fill 的 4 列（68–83px）更差。判据本是「右栏多宽」，CSS 只能用视口断点近似，
 *     故按上表实测反推分档，**别再凭感觉改这些断点**。
 *   ⚠️ 取值少于 7 个（如 3 个）时右侧会有 4 格空白 —— 这是「一排 7 个」的必然代价，不是漏项。
 * 只使用既有令牌，不新增（新令牌必须定义在 base.css:root 才两端稳，见 test/css-token-scope-smoke）。 */
.pd-dim-bar{margin:8px 0 2px}
.pd-dim-h{display:flex;align-items:baseline;gap:8px;margin-bottom:8px}
.pd-dim-name{font-size:12.5px;color:var(--t4)}
.pd-dim-cur{font-size:12.5px;font-weight:600;color:var(--t1)}
/* 🔴 max-height = **三行瓦片的自然高（341px）**（2026-10-24 起；此前是两行 202px）。
 *   为什么从两行变三行：固定 7 列后 **15–21 个取值**会排到 3 行（原来 8 列时 16 个值正好 2 行）。
 *   若仍保持原上限，第 3 行会被裁成内滚 —— 那正是 2026-10-11 被掌柜否掉的形态。
 *   同日两档叠加（都是掌柜当天的指令，别单独拎一条来质疑数值）：
 *     ① 「一排 7 个」⇒ 列数 8→7、上限 202→305（三行）；
 *     ② 「缩略图放大到 68 左右」⇒ 图 56→68、行高 95→**107** ⇒ 上限 305→**341**。
 *   实测（真浏览器，克隆瓦片到目标数量）：14 值 → 2 行 / 226px、15 值 → 3 行 / **340px**、
 *   21 值 → 3 行 / 340px，三者 `scrollHeight === clientHeight`（**零内滚**）⇒ 341 是三行临界
 *   （107×3 + 8×2 + 4 = 341）。
 *   ⚠️ 代价只落在 **≥15 取值** 的商品（比两行多占 114px 高）；≤14 取值时 max-height 不生效 ⇒ **零代价**。
 *   ✅ **覆盖面反而变大**：原来 8 列 × 2 行 = 16 个值，现在 7 列 × 3 行 = **21 个值**。
 *   ↓ 以下为历史沿革（2026-10-11 那次的口径），保留以免误以为「两行」这条被废弃：
 * 固定上限，**不随视口压缩**。
 *   掌柜 2026-10-11 点选本网格 →「**上下最高点，尽量两行时不用下拉**」＝ 取高度上限，
 *   保证 16 色这类**两行**排布时**网格自身不出现内滚**（不必在下拉里找后几个颜色）。数值按实测反推：
 *     · 一个瓦片行 = 56(图) + 2(图↔标签间距) + 28.75(标签两行 = 2.5em×11.5px) + 6(瓦片上下内边距) + 2(边框) = 94.75px
 *     · 两行自然高 = 94.75×2 + 8(网格行间距) + 4(网格上下 padding) = 201.5px ⇒ 上限取 **202**，留 0.5px 余量
 *       （test/cdrawer-smoke.js 第 16.3 组就是拿这 201.5 与上限对拍）
 *     · 演进轨迹（都是掌柜逐次点选定的，别随手改回去）：
 *         原始 48 图/内边距 6/间距 4 → 上限 216（**7 列 3 行 + 内滚 88px**，后 2 色看不见）
 *         ↓ 收瓦片宽 72→64（7→8 列，16 色才真成两行）+ 图压到 40、内边距/间距照旧
 *         ↓ 掌柜「尽量两行时不用下拉」⇒ 图 40、内边距 3、间距 2 ⇒ 两行 185.5、上限 186（**零代价**）
 *         ↓ 掌柜「缩略图还能再做大点吗」⇒ 图 **56** ⇒ 两行 201.5、上限 **202**（本档，+16px 代价）
 *       每 +4px 图高 = 两行 +8px = 规格行免下拉临界视口 +8px。**再往上只剩满宽方形 59.5**（上图 +7 = +14）。
 *         ↓ 2026-10-24 掌柜两轮追加：「一排 7 个、卡片拉宽」→ 列数 8→7；「缩略图放大到 68 左右」→ 图 68
 *           ⇒ 行高 **107**、三行上限 **341**（当前档；图已顶到内容宽 69 的物理上限，没有下一档了）。
 *     · test/cdrawer-smoke.js 第 16.3 组**从这些 CSS 值现算一遍**与上限对拍 ——
 *       任一处（缩略图高 / 标签行数 / 瓦片内边距 / 网格 gap 与 padding）改动而没同步上限，即报红。
 * 🔴 **与「规格行免下拉」是同一列纵向空间的互相挤占**。同日早些时候那版用的是
 *   `clamp(112px, 100vh − 780px, 186px)`：矮视口把色块压到内滚、换取规格 5 行免下拉。
 *   掌柜看过实物后改口径 ⇒ **色块优先**：矮视口下色块不再让步，代价转移到规格行的外部下拉。
 *   实测（宽 1440 / 5 行最坏用例）：**色块在 1080~850 全档都是 8 列 / 2 行 / 185.5 / 零内滚**；
 *   规格行的缺口随视口变矮而变大 —— vh ≥ 934 免下拉、930 差 4px、900 差 34px、850 差 84px。
 *   🔴 **这两个数（免下拉临界视口 / 缺口）依赖商品标题占几行**，不是纯代码常量：
 *     本商品标题 23 字 ⇒ 页头 1 行（`.page-head` 实测 63.9px）；若标题长到两行，页头 +31.7px，
 *     上述临界视口与缺口**同步右移 ~32px**。故别把它当硬阈值引用，判断「够不够」一律实测。
 *   `overflow-y:auto` 保留：**3 行以上**的网格（如 24 色）仍走网格内滚 ——
 *   掌柜的「两行时不用下拉」不覆盖那种情形（那时无论如何都装不下）。 */
.pd-dim-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;
  max-height:341px;overflow-y:auto;padding:2px 4px 2px 2px;scrollbar-width:thin}
/* 🔴 瓦片几何：**用内部留白换图高**（2026-10-11 掌柜「这个模块里的缩略图还能再做大点吗」）
 *   内边距 6→3、图↔标签间距 4→2，共省 **12px/行**，正好等于图高 40→48 的增量
 *   ⇒ `rowH = 48(图) + 2 + 28.75(标签两行) + 6(上下内边距) + 2(边框) = 86.75px`，**与改前逐位相等**。
 *   🔴 因此 `.pd-dim-grid` 的 186 上限与「规格行免下拉」预算**分文未动** —— 这是本模块
 *   唯一能做到「图变大而零代价」的档位（图 40×40 → 48×48，**面积 +44%**）。
 *   ⚠️ 内边距不能再往下压：选中态是 `border + inset 1px 描边`，留白少于 3px 时描边会贴到图上。
 *   ⚠️ 再想更大（52 / 56 / 满宽方形 59.5）就必须**抬高 `.pd-dim-grid` 的上限**，从规格行的
 *   免下拉预算里拿 —— 对应缺口与临界视口的实测值见 `pages.css` 上方的表格与开发日志。 */
.pd-dim-opt{display:flex;flex-direction:column;align-items:center;gap:2px;padding:3px 4px;max-width:96px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--canvas);cursor:pointer;
  font-family:inherit;transition:border-color .15s,background .15s}
.pd-dim-opt:hover{border-color:var(--pri)}
.pd-dim-opt.on{border-color:var(--pri);background:var(--pri-weak);box-shadow:inset 0 0 0 1px var(--pri)}
/* 缩略图 **56px**（2026-10-11 掌柜「这个模块里的缩略图还能再做大点吗」→ 选定 56 档）。
 *   商品图基本是方图（本商品实测原图 **800×800**）+ `object-fit:contain`
 *   ⇒ **实际画出的图形边长 = min(瓦片内容宽 59.5, 图区高)**，只加框高是没用的：
 *     40 时图形只有 40×40（框比图大，白占行高）；48 时 48×48；56 时 56×56；59.5 才顶到物理上限。
 *   📌 **2026-10-24 两轮之后的上限与余量**：瓦片 68→79px（一排 7 个）⇒ 内容宽 59.5→**69px**，
 *     掌柜随即要求「缩略图放大到 68 左右」⇒ 图取 **68px**，**几乎顶满 69 的内容宽**
 *     （实测渲染 69×68 元素盒、画出的图形 68×68）。再往上只有 1px，没有意义。
 *     ⚠️ 图 56→68 的代价：行高 95→107（+12/行）、两行多 24px、上限 305→341。
 *     901–1240 窄右栏档（瓦片 68–83px）里图会被**宽度**卡到 58–73px，比 68 略小 —— 物理限制，非缺陷。
 *   🔴 上限就是瓦片内容宽 59.5px（= 瓦片 69.5 − 左右内边距 2×4 − 边框 2）——
 *     图区再高也不会让图变大（图被宽度卡住），只会白占行高。**再加宽需减列（16 色就变 3 行），不划算。**
 *   ⚠️ 本档**不是零代价**：图 48→56 使瓦片行 +8px、两行 +16px ⇒ `.pd-dim-grid` 上限 186 → **202**
 *     （必须同步，否则两行被裁、网格出内滚，违反掌柜「两行不打折」）。代价 = 规格行免下拉临界 934 → 950px。 */
.pd-dim-th{display:flex;align-items:center;justify-content:center;width:100%;height:68px;overflow:hidden}
.pd-dim-th img{width:100%;height:100%;object-fit:contain}
/* 🔴 高度必须维持**两行**（`2.5em` = 1.25 行高 × 2）：实测「复古绿」与「复古绿-方形本」前 3 字相同，
 *   砍成 1 行后两个瓦片渲染出**一模一样的「复古绿」**，用户无法区分 —— 那是缺陷不是省空间。
 *   窄屏（≤560）曾把它压成 1.25em，已一并改回。 */
.pd-dim-lb{width:100%;height:2.5em;overflow:hidden;overflow-wrap:anywhere;text-align:center;
  font-size:11.5px;line-height:1.25;color:var(--t1)}
/* 规格列表的引导行（2026-10-11 掌柜指令「这个模块上面增加一行文字，选择规格」）。
 * 位置：色块网格与规格行之间 —— 正是原「规格表头」所在处，承接它留下的语义空位，但**只留文案**：
 *   不做 sticky、不加底色、不画分隔线（那三样恰是被掌柜删掉的表头形态，别顺手复活）。
 * 🔴 卡片顶部原有一枚同文案的卡片级标题（单维渲染 / 多维不渲染），已**整体下线** ——
 *   否则单维商品会在同一屏出现两处「选择规格」，且同一句话在两种商品上会有不同视觉语法。
 * 高度：本行实测 **19.2px**（12px × 1.6 行高）+ 上间距 6px = **25.2px**，
 *   吃掉刚兑现的 28.2px 里的 25.2px ⇒ **净仍省 3px**；免下拉临界视口 918 → **945px**（实测 945 ✅ / 940 差 5px）。
 *   ⚠️ 别再顺手加大它的字号/间距：这一行是纯引导文案，每一 px 都是从规格行的免下拉预算里出的。
 *   （两者互为挤占的关系，与本文件里色块网格那段的道理相同。） */
.pd-sku-list-h{margin-top:6px;font-size:12px;color:var(--t4)}
/* 【2026-10-14 掌柜指令】规格列表行间留白 = **5px**，取代原来的「每行一条 border-top」——
 *   分隔线是「表格」语法（线与线之间仍然是贴着的），`gap` 才是「隔开」。
 * 🔴 只在 `.pd-sku-list` 上写 `row-gap`：行本身不再带 border（见 `.pd-sku-row`）。
 *   ⚠️ 若日后有人把行改回带 border-top，会与这个 gap 叠加成「线飘在空隙里」，很脏。
 * 🔴🔴 **间距必须明显大于行内距，否则等于没改**（本轮第一版就栽在这）：
 *   第一版取「行内距 6 + 间距 5」，**总留白与改前完全一样**（6+5+6 = 17px ＝ 改前 8+1+8 = 17px）——
 *   只是把那条 1px 分隔线拿掉了，肉眼看上去「还是挨着」。间距要能被眼睛读成「分界」，
 *   就得**远大于行内距**。现取 **行内距 5 / 间距 12（2.4 : 1）** ⇒ 两行内容之间 22px（改前 17px）。
 * 🔴 **代价必须说清**：每行节距 61 → 66（缩略图行），**每行 +5px**；10 行商品列表 +50px。
 *   规格列表总高直接决定「规格多到免下拉」的临界视口（见 `.pd-sku-list-h` 那段）⇒
 *   实测临界会从 945px 上移到 ~995px。**这是掌柜为「分得开」明确付的代价**，若要收回，
 *   第一个该动的旋钮就是这个 `row-gap`（调到 8 则每行只 +1px）。
 *   📎 实测（`_assess/tmp/skugap/`）：稳态节距 66（改前 61）、行间距 12、行高 54（缩略图行）。 */
.pd-sku-list{display:flex;flex-direction:column;row-gap:12px;margin-top:4px}
/* 单行规格行（2026-10-11 掌柜指令重构）：缩略图 · 规格名 · 售价 · 数量步进。
 * 原为「名称 + 副行（单位 · 售价）」两行，现压成一行、去掉单位、字号整体上调一号。
 * 🆕 【2026-10-14 掌柜指令】行与行要「隔开」—— 掌柜原话：「行与行之间留一点间距。现在我看的是挨着的，
 *   最好是视觉上能分得开，上下两行中间有隔开的那种感觉。」
 *   ⇒ ① **撤掉每行的 `border-top` 分隔线**（那是「表格」语法，线与线之间仍是贴着的）；
 *      ② 间距改由 `.pd-sku-list` 的 `row-gap` 承担（见上一条），行**各自成块**（`border-radius:10px`
 *         这才第一次真正可见 —— 贴着的时候圆角是画不出来的）；③ 行内上下内距 8 → **6px 补偿**，
 *         使「行高 + 间距」的总节距与改前基本持平（改前 61px/行，改后 60px/行）——
 *         🔴 规格列表的高度直接决定「规格多到免下拉」的临界视口（见 `.pd-sku-list-h` 那段），
 *         不能因为美观把这份预算悄悄吃掉。 */
.pd-sku-row{display:flex;align-items:center;gap:12px;padding:5px 10px;
  border-radius:10px;transition:background .15s;cursor:pointer}
/* 【2026-10-14 掌柜指令】整行都是「预览这一条规格」的点选目标（行上挂了 data-act="sku-img"）
 * ⇒ 行显示手型。🔴 `cursor` 是**继承**属性 ⇒ 数量框必须显式复位成输入型光标，
 *   否则「能打字的地方」看起来像「点一下就预览」（± 按钮保留继承来的手型 —— 它们确实可点）。 */
.pd-sku-row .pd-qty{cursor:text}
/* ⚠️ `.pd-sku-row:first-child{border-top:0}` 已随「行不再有分隔线」**删除** ——
 *   留着它就是死规则，且会让人误以为行上还该有 border-top。 */
.pd-sku-row:hover{background:var(--sf2)}
.pd-sku-row.on{background:var(--sf2)}          /* 预览中（点了名称 / 缩略图） */
/* 「已填数量」的行：淡蓝底 + 左侧色条（用 inset 阴影而非 border-left —— 后者会撑开行宽、
 * 让价格列与步进整体右移，列就对不齐了）。放在 .on 之后 ⇒ 同时命中时以「已选」为准。 */
.pd-sku-row.sel{background:var(--pri-weak);box-shadow:inset 3px 0 0 var(--pri)}
.pd-sku-row.hide{display:none}   /* 筛选未命中（不删行、不动数据） */
/* 【2026-10-11 掌柜点选删除】原「规格表头」那一行（规格 / 售价 / 数量）已**整条下线**，
 * 连同它的 5 条列规则（表头本体 / 缩略图占位 / 名称 / 售价 / 数量）与 ≤560 的 3 条镜像规则。
 * 口径：列语义已由行内自身承载（名称在左、售价右对齐、步进在最右），三列表头属**重复文案** ——
 *   掌柜当日连续做减法（筛选框 → 计数 → 清空数量 → 表头），风格一致。
 * 🔴 顺带**兑现 28.2px 高度**（实测原表头高：padding 4×2 + 12px 行高 + 1px 下边框）
 *   ⇒ 规格列表可用高度 +28.2px ⇒ 「规格行免下拉」**临界视口实测 950 → 918px**
 *   （1440 宽 / 5 行最坏用例：vh≥918 免下拉、900 差 20px、850 差 70px）。
 * 🔴 随之作废的是**列宽对拍**：表头原是「表头 ↔ 行」两侧宽度的对拍锚点，靶子没了
 *   ⇒ 该组断言整组下线（是**靶子没了**，不是放宽判据）。仍守的是
 *   **行内步进宽度取自 `--pd-step-w` 且可从 base.css 现算** —— 那是真正的**跨文件**一致性。
 * 🔴 表头原带 `position:sticky`；删除它**不影响** `.pd-buy` 的吸顶（那是另一套机制）。
 * ⚠️ 本注释刻意不写旧类名 —— test/cdrawer-smoke.js 有防回填守卫，出现即报红。 */
/* 行首「规格图缩略图」（2026-10-11）：1688 采集回来的 `specs[].img`。
 * 由 JS 决定出不出这一列 —— **全部规格都没有专属图时整列不渲染**（否则 N 行同一张商品主图，纯噪音）。
 * object-fit 用 contain 与 .gal-th 一致：缩略图只缩小、不裁切商品。 */
.pd-sku-th{flex:0 0 auto;width:44px;height:44px;border:1px solid var(--line);border-radius:8px;
  background:var(--canvas);overflow:hidden;display:flex;align-items:center;justify-content:center;
  cursor:pointer;transition:border-color .15s}
.pd-sku-th:hover{border-color:var(--pri)}
.pd-sku-th img{width:100%;height:100%;object-fit:contain}
.pd-sku-row.on .pd-sku-th{border-color:var(--pri)}
.pd-sku-main{flex:1 1 auto;min-width:0;cursor:pointer}
.pd-sku-lb{font-size:15px;font-weight:600;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 售价列：紧贴步进**之前**、占固定最小宽并右对齐 + 等宽数字 ⇒ 小数点竖向对齐，比价可竖着扫读。
 * 颜色取 --ink（与详情页主价格 .price-line .p 同源），不用强调色 —— 一列蓝字反而压过规格名。 */
/* 【2026-10-21 包装换算】价格后面跟「/ 盒」「/ 件」—— 跨单位商品里，光有金额没有量纲
 *   客户根本判断不了「¥135 是每箱还是每支」（真实现场）。单位走行内小字，**不改行高**：
 *   规格列表高度直接决定「免下拉」的临界视口（见 .pd-sku-list 那段预算），不能被吃掉。 */
.pd-sku-pu{margin-left:2px;font-size:12px;font-weight:400;color:var(--t3);white-space:nowrap}
.pd-sku-price{flex:0 0 auto;min-width:106px;text-align:right;font-size:15px;font-weight:600;
  color:var(--ink);font-variant-numeric:tabular-nums}
/* 【2026-10-24 A5】规格行「缺货 · 预询」小标 + 选中规格缺货提示条。
 * 规格行的空间预算很紧（.pd-sku-list 的可视高度直接决定「免下拉」临界视口），
 * 故小标**折到价格下方**、不占横向宽度，也不增加行高（行高由 44px 缩略图撑着）。
 * 颜色用既有 amber 族令牌，不引入新色相。 */
.pd-sku-st{display:block;margin-top:2px;font-size:11px;font-weight:600;
  color:var(--warn-ink);white-space:nowrap;line-height:1.1}
.pd-sku-row[data-pre="1"] .pd-sku-price{color:var(--t2)}
.pd-stock-warn{margin-top:8px;padding:7px 10px;border-radius:var(--r-sm);
  background:var(--warn-weak);color:var(--warn-ink);font-size:12px;font-weight:600;line-height:1.4}
.pd-stock-warn[hidden]{display:none}
/* 宫格页卡片：缺货款在价格下方补一行（卡片底部有 8px 余量，不会撑破卡片高度） */
.pg-card-st{display:block;margin-top:2px;font-size:11px;font-weight:600;color:var(--warn-ink);line-height:1.1}
.pg-card.is-pre{background:var(--warn-weak)}
/* 行内步进：数量下限 0 = 本次不采购该规格（行上以 data-p 预置客户专属价，供合计与批量加购）。
 * 🔴 宽度收敛到唯一来源 `--pd-step-w`（表头删除后它只服务行内步进，但**仍要收敛**：
 *   步进的实际几何由 base.css 决定，若不变量化，改 base.css 时无人能发现行内栅格已被撑坏）：
 *   客户端壳内的步进几何由 base.css:1099-1104 的 `.shell.hc-c .stepper …` 决定
 *   （胶囊形：padding 4 + border 1 + button 26 + 输入框 36 + gap 2）
 *   ⇒ 实宽 = 4×2 + 1×2 + 26×2 + 36 + 2×2 = **102**。
 *   ⚠️ 早期这里写过 `.pd-step button{width:30px}` / `.pd-step b{width:50px}` —— 那是**死规则**：
 *   `.shell.hc-c .stepper button`（0,2,1）特异度高于 `.pd-step button`（0,1,1），从来不生效，
 *   按它推出的「118」当年正是列错位 16px 的根源。已删除，只留宽度这一个变量。
 *   🔴 若日后改动 base.css 的步进几何，**必须同步改 `--pd-step-w`** —— test/cdrawer-smoke.js
 *   会从 base.css 现算一遍实宽与之对拍，不同步即报红。 */
.pd-cols{--pd-step-w:102px}
.pd-step{flex:0 0 var(--pd-step-w)}
/* 底部合计（「已选 N 件 · K 个规格」+ 金额） */
.pd-sum{display:flex;align-items:baseline;gap:8px;margin-top:12px;font-size:13px;color:var(--t4)}
.pd-sum.on{color:var(--t3)}
.pd-sum .pd-sum-n b{color:var(--ink)}
/* 「隐藏 y 条已填数量（已计入）」：紧贴合计文案、在金额左侧。
 * 🔴 它是**必要解释**不是装饰 —— 合计含被筛掉的行，没有这句，用户看到
 *   「金额 > 可见行之和」会当成算错（原挂在被删除的计数位上，2026-10-11 迁到此处）。
 * 只在真有隐藏的已填行时才由 UI_skuSum 写入文案，平时是空的（不占视觉噪音）。 */
.pd-sum .pd-sum-hid{font-size:12px;color:var(--warn-ink);white-space:nowrap}
.pd-sum .pd-sum-t{margin-left:auto;font-size:18px;font-weight:600;color:var(--promo);letter-spacing:-.3px}
/* ---------- 断点：>1240 等分 700/700｜≤1240 右栏**连续流体**｜≤900 单列 ----------
 * 2026-10-13 分辨率自适应改造：右栏原为「400px(≤1240) / 360px(≤1080)」两档硬值 ——
 *   在 1080 处右栏会一次跳 40px。改为一条 clamp 后，右栏宽随视口连续变化：
 *   @1240 → 32.3vw = 400.5 → 钳到 400（**与原设计精确对齐**，观感不变）
 *   @1080 → 348.8（原 360，差 11px）
 *   ≤901 → 触底 340（此时左栏图集多拿到 20px，对它更有利）
 *   原 ≤1080 那条已删 —— 本条的媒体条件 1240 已覆盖它的作用域。 */
/* 【2026-10-14】窄栏收缩白卡内距：本档右栏是 clamp(340px,32.3vw,400px)，视口 901–1053 时常驻 340px，
 * 24px 内距会吃掉 48px 把规格名压没 ⇒ 收到 16/12（≤900 单列全宽时再恢复 24px，见下一个媒体块）。
 * 🔴 真机实测（1000×800 + **带规格图**的商品，最坏情况）：规格行固定占用
 *   缩略图 44 + 价列 78 + 步进 102 + 间距，白卡再吃 24px 后规格名只剩 30px（约 2 字）。
 *   故本档同时把售价列下限 78→66（真机复测后规格名回升到 ~42px）。仅窄栏生效，宽栏不动。 */
@media (max-width:1240px){ .pd-cols{grid-template-columns:minmax(0,1fr) clamp(340px,32.3vw,400px);column-gap:clamp(20px,2.1vw,26px)} .pd-buy{padding:16px 12px} .pd-sku-price{min-width:92px}
  /* 【2026-10-24】本档仍是**两列**，但右栏被 clamp 收到 340–400px（实测网格内宽 310–370px）；
   * 7 列在这里只剩 37–45px（缩略图 56 都被压缩），比 auto-fill 的 4 列（71–86px）更差 ⇒ 降到 4 列。
   * 「一排 7 个」只在右栏够宽（>1240 档，网格 548–618px）与单列档（≤900，网格 650–790px）成立。 */
  .pd-dim-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (max-width:900px){
  /* 单列：图集 → 购买 → 页签（手机购物习惯：先看图与价，再读长内容）。
   * 🔴 2026-10-14 三改后左列被 `.pd-left` 包住 ⇒ 用 `display:contents` 把图集与页签**放回网格**，
   *   再用显式 `grid-row` 排回「图集 1 / 购买 2 / 页签 3」——**顺序与两列档完全一致**（客服/掌柜既有习惯不变）。
   *   该档下视觉顺序 ≠ DOM 顺序（DOM 是 图集→页签→购买），已在 `.pd-cols` 上方注明。 */
  .pd-cols{grid-template-columns:1fr}
  .pd-left{display:contents}
  .pd-gallery{grid-column:1;grid-row:1}
  .pd-buy{grid-column:1;grid-row:2}
  .pd-tabs{grid-column:1;grid-row:3;margin-top:0}   /* 单列档的上下间距由 .pd-cols 的 row-gap:22px 承担 */
  .pd-buy,.c-drawer-body .pd-buy{position:static;top:auto;max-height:none}
  .pd-buy{padding:24px}   /* 【2026-10-14】单列全宽 ⇒ 收回 ≤1240 档的窄栏收缩，恢复满档内距 */
  .pd-buy-body{overflow:visible}   /* 单列下整页自己滚，中段不再单独滚动 */
  .pd-gallery{flex-direction:column-reverse}
  .pd-rail{flex:0 0 auto;flex-direction:row;flex-wrap:wrap}   /* 换行而非横向滚动：不新增滚动容器 */
  .pd-cols .pd-gallery .prod-img{max-width:none}
  /* 单列态 `.pd-buy` 已 max-height:none、整页自滚 ⇒ 右栏无需为规格行「让位」，色块取更宽的上限。
   * 🔴 但**不得低于两行自然高 201.5px** —— 单列下瓦片更宽、16 色同样是 2 行，
   *   压到两行以下就会出网格内滚（违反掌柜「两行不打折」）。 */
  /* ≤900 已转单列全宽（实测网格 650–790px），7 列回到 85–96px ⇒ 把上一档的 4 列写回。
   * 上限给到 320 是 7 列下「15+ 取值 = 3 行」的需要（行高 95：95×3+8×2+4 = 305）。 */
  .pd-dim-grid{grid-template-columns:repeat(7,minmax(0,1fr));max-height:341px}
}
/* 极窄（手机）：掌柜要的「单行」放不下 —— 缩略图 44 + 售价 78 + 步进 118 + 三处间距已占 276，
 * 留给规格名的宽度会**归零**（实测：列表 300px ⇒ 规格名 0px，名字完全看不见，只剩图和价格）。
 * 故 ≤560px 折成两行：① 缩略图 + 规格名 ② 售价 + 数量步进（整体右对齐）。
 * 桌面与平板维持单行，不受影响。 */
@media (max-width:560px){
  .pd-sku-row{flex-wrap:wrap;row-gap:8px}
  .pd-sku-main{flex:1 1 calc(100% - 56px)}   /* 56 = 缩略图 44 + 行内间距 12 ⇒ 名称占满第一行剩余 */
  .pd-sku-price{margin-left:auto}            /* 售价与步进一起被挤到第二行并靠右 */
  /* 【2026-10-11】原这里还有 3 条「表头照同一套折行规则走」的镜像规则 —— 表头已按掌柜指令删除，
   * 镜像规则一并下线（窄屏不再有「表头与行错位」这个问题）。 */
  /* 维度选择器：窄屏缩到 4 列、缩略图压到 44px。
   * 标签**维持两行**（原为 1.25em）：「复古绿」与「复古绿-方形本」前 3 字相同，
   * 压成一行会让两个瓦片显示成同样的文字、无法区分 —— 窄屏本就整页滚，辨识度优先。
   * 刻意**不引入横向滚动** —— 那会新增一个滚动域（需登记 SCROLLER_SEL），换来的是更难点的横滑。 */
  .pd-dim-grid{grid-template-columns:repeat(4,minmax(0,1fr));max-height:210px}
  .pd-dim-th{height:44px}
  /* 【2026-10-24】加购弹窗的维度选择器（`.pk-dim-*`，与详情页同构的另一套）：
   * 弹窗宽 = `min(760px, 100vw)`，≤560 视口时网格只剩 340–480px ⇒ 7 列会掉到 41–61px，
   * 与详情页同样的问题 ⇒ 降 5 列（61–89px）。宽档（>560）仍是 7 列 / 94px。 */
  .pk-dim-grid{grid-template-columns:repeat(5,minmax(0,1fr))}
  .pd-dim-lb{height:2.5em}
}

/* ============================================================
 * 购买包装（2026-10-22）· 独立于属性规格维度，**不带任何图片**
 * 口径：包装只决定「买多少」，不改变「买哪个货」，也不改变单价。
 * 🔴 本段**只加不改**：不复用也不覆盖任何既有 .pd-* 的尺寸与形态；
 *   与规格区之间由 `.pd-buy-body .pd-blk + .pd-blk` 的既有 18px 间距 + 下面这条发丝线分隔。
 * 🔴 颜色一律走变量（门禁只扫 JS，不扫 CSS —— 写死色值这里不会有任何报错）。
 * ============================================================ */
.pd-blk-pk{border-top:1px solid var(--line3);padding-top:14px}
.pd-blk-pk .pd-blk-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.pd-blk-sub{font-size:12px;color:var(--t5)}
.pd-pk-list{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.pd-pk-opt{display:inline-flex;align-items:baseline;gap:6px;max-width:100%;padding:7px 12px;border:1px solid var(--line3);border-radius:8px;background:var(--canvas);font:inherit;font-size:13px;line-height:1.4;color:var(--t2);cursor:pointer;transition:border-color .15s,background-color .15s,color .15s}
.pd-pk-opt:hover{border-color:var(--pri);color:var(--pri-600)}
.pd-pk-opt.on{border-color:var(--pri);background:var(--pri-weak);color:var(--pri-600);box-shadow:inset 0 0 0 1px var(--pri)}
.pd-pk-nm{font-weight:600}
.pd-pk-fold{font-size:12px;color:var(--t4);white-space:nowrap}
.pd-pk-opt.on .pd-pk-fold{color:var(--pri-600)}
.pd-pk-tip{margin-top:8px;font-size:12px;color:var(--t4)}
.pd-pk-tip b{color:var(--t2);font-weight:600}

/* 加购弹窗规格行的单价后缀（2026-10-22）：单价恒为「每 1 个基准单位」，
 * 不带这个后缀时，客户切到「箱」买会把它读成箱价。与详情页 `.pd-sku-pu` 同一口径。 */
.pk-price .pk-pu{font-size:12px;color:var(--t4);margin-left:2px;font-weight:400}
/* ============================================================
 * 【2026-10-24】规格宫格页（商品级 products.disp='grid'）
 * 左 1/3 主图 + 右 2/3 卡片宫格 + 吸底购买条。
 * 🔴 不复用 .pd-cols / .pd-left / .pd-buy：
 *     · .pd-left 带 `min-height:calc(100vh - 160px + 200px)`（给 sticky 右栏留行程），
 *       在这个 1/3 窄列上会撑出半屏空白；
 *     · .pd-cols 的列宽与 --pd-step-w 被 cdrawer-smoke 逐字钉住，动它会假红。
 * 🔴 断点只允许 1240 / 1080 / 900 / 560（responsive-breakpoint-smoke 白名单）。
 * ============================================================ */
.pg-wrap{margin:0 auto;max-width:1440px}
.pg-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2.05fr);column-gap:24px;align-items:start}
/* sticky 列现在含「主图 + 购买条」两块 ⇒ 矮屏可能高于视口。给它一个上限并允许内部滚动，
       * 否则粘住时底部的按钮会永远够不到（sticky 元素比视口高时，下半截滚不出来）。
 * 【2026-10-24 掌柜】图区与购买区要**分得清**：两块的间距交给 flex gap（不再靠 `.pg-bar` 的
 *   margin-top），购买条自己是一张有边框的白卡（见 `.pg-bar`）。
 * 🔴 左右/底部各留 2px、10px：`.pg-side` 是 `overflow-y:auto` 的滚动容器，**子元素的 box-shadow
 *   会在容器边界被裁掉** —— 不留缝隙时卡片看起来"左右下边框消失"，只剩贴着上沿的一条线。 */
.pg-side{position:sticky;top:8px;align-self:start;max-height:calc(100vh - 16px);overflow-y:auto;scrollbar-width:thin;
  display:flex;flex-direction:column;gap:18px;padding:0 2px 10px}
/* 🔴 子项必须 `flex-shrink:0`：容器高度受限时，纵向 flex 会**压扁图片**去凑高度（实测图会变扁），
 *   而这里要的是「内容超了就滚动」，不是「挤一挤塞进去」。 */
.pg-side>*{flex:0 0 auto}
/* ============================================================
 * 左栏主图区（2026-10-24 掌柜：主图与购买区要有信息层次）
 * 改前：图直接浮在页面底上，图注是**两行散字、没有归属容器** —— 视觉上是
 *   「一张图 + 两行字」，读的人分不清那两行是在说图还是在说购买条。
 * 改后：图与图注合成**一张卡**（与下方购买条同一家族：白底 + 真 border + 大圆角），
 *   图注变成卡内的下半栏（细分隔线 + 左右两栏）。
 * 🔴 结构上 `.pd-gallery.pg-hero` 仍是外层容器（灯箱 zoom-img 与 gal-pick 按这组选择器找图），
 *   只加外观、不动层级。`.pg-hero{display:block}` 必须保留：`.pd-gallery` 本来是 flex，
 *   不改回 block 的话图注会跟图并排。
 * ============================================================ */
.pg-hero{display:block;background:var(--canvas);border:1px solid var(--line2);border-radius:var(--r-lg);overflow:hidden}
/* 主图尺寸：标准页的 `.prod-img` 是 **固定 350×350 + flex-shrink:0**（base.css:287），
 * 直接搬进 1/3 窄列会向右溢出、压住右栏标题（实测 1200 宽下压掉第一个字，且因为
 * `.pg-side` 是 sticky 会盖在上层，看起来像"标题被裁"）。这里改成跟随列宽的正方形。 */
.pg-hero .pd-hero{min-width:0;width:100%;padding:9px}
/* 🔴 必须写三层（0,3,0）：base.css:1146 的 `.shell.hc-c .prod-img` 是 (0,3,0)，
 *   两层选择器会被它压掉（背景色与 18px 圆角都改不动，且没有任何报错）。
 *   pages.css 在 base.css 之后加载 ⇒ 同特异度时后者胜出。 */
.pg-hero .pd-hero .prod-img{width:100%;height:auto;aspect-ratio:1/1;flex-shrink:1;background:var(--surface);border-radius:10px}
/* 图注：卡内下半栏。左侧「规格名 + 订货编码」，右侧「第 N / 共 M 款」。
 * 🔴 原来那句「点击右侧规格卡片切换图片」已删：学会一次就没用的操作说明，常年占一行。 */
.pg-hero-cap{display:flex;align-items:flex-end;justify-content:space-between;gap:8px;
  padding:9px 12px 11px;border-top:1px solid var(--line3)}
.pg-hero-nm{display:flex;flex-direction:column;gap:3px;min-width:0}
.pg-hero-cap b{font-size:14px;font-weight:500;color:var(--t1);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pg-hero-cap span{font-size:11px;color:var(--t5)}
.pg-hero-idx{flex:0 0 auto;font-size:11px;color:var(--t5);white-space:nowrap;font-variant-numeric:tabular-nums}
.pg-main{min-width:0}
.pg-box{background:var(--canvas);border-radius:var(--r-md);box-shadow:var(--sh1);padding:14px 16px 16px}
.pg-box .page-head{margin-bottom:10px}
.pg-tools{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px;background:var(--sf);border-radius:var(--r-sm);margin-bottom:12px}
.pg-q{flex:1 1 200px;min-width:150px;height:30px;border:1px solid var(--line2);border-radius:var(--r-sm);padding:0 10px;font-size:13px;color:var(--t1);background:var(--canvas)}
.pg-q:focus{outline:none;border-color:var(--pri)}
.pg-chk{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--t3);white-space:nowrap;cursor:pointer}
.pg-sort{height:30px;border:1px solid var(--line2);border-radius:var(--r-sm);background:var(--canvas);font-size:12px;color:var(--t2);padding:0 6px;cursor:pointer}
.pg-cnt{font-size:12px;color:var(--t5);margin-left:auto;white-space:nowrap}
.pg-cnt b{color:var(--t2);font-weight:600}
.pg-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:14px}
/* ============================================================
 * 宫格卡片（2026-10-24 掌柜：白底图时整片发糊，信息层次不清）
 * 根因不是「边框太细」，而是**三层颜色挤在同一档对比度**（实测量取）：
 *   卡片边框 vs 页面底 1.07 ｜ 边框 vs 卡片白底 1.15 ｜ 图区底 vs 卡片白底 1.05
 * WCAG 里 1.5 以下基本等于「没有边界」⇒ 白底图铺满 160×160 后，图、卡、页面连成一片。
 * 修法三条（缺一条都不够）：
 *   ① 图改 `contain` + 图区内距：白底图退成 144px 的白块浮在灰底上，
 *      边界从「1px 细线」变成「144px 长边」—— 这是白底图能看清的关键；
 *   ② 图区底 `--sf #F7F8FA` → `--surface #F1F3F6`，与卡片白底拉开；
 *   ③ 边框 `--line` → `--line2`（#D5DAE1），对比度 1.07 → 1.30，进入「看得见」的区间。
 * 🔴 边界一律用**真 border**，绝不用 `--sh1`：客户端作用域的 `--sh1` 是 `0 0 0 1px`
 *   描边环（base.css:928），外扩画在元素外，遇到 overflow 容器会被裁掉（购买条已栽过）。
 * 🔴 文字层级刻意**反过来**：200 个 SKU 里找货靠名称，不能让价格比名称更抢眼
 *   ⇒ 名称 400→500，价格 15px→14px（仍是红色 + 600，依旧醒目）。
 * ============================================================ */
.pg-card{position:relative;display:flex;flex-direction:column;padding:0;border:1px solid var(--line2);border-radius:12px;background:var(--canvas);overflow:hidden;cursor:pointer;text-align:left;font:inherit;color:inherit;transition:border-color .12s,box-shadow .12s}
.pg-card:hover{border-color:var(--pri-200)}
.pg-card.on{border-color:var(--pri);box-shadow:inset 0 0 0 1px var(--pri)}
/* 🔴🔴 图区必须建立**独立层叠上下文**（`z-index:0` 即可，不需要 isolation）。
 *   原因：下面 `.pg-card-img img{z-index:1}` 是为「图盖住首字垫底」而设的，
 *   但它属于**卡片这一层**的层叠上下文 ⇒ 会把 `.pg-card-ck` / `.pg-card-ct` 一起压下去。
 *   实测（2026-10-24 掌柜反馈「圆圈被图片遮住，只露出一个小小的半圆」）：
 *   18×18 的选中角标与图片重叠 **16×16**，只有外侧 2px（图区 padding 那圈）露出来；
 *   `elementFromPoint` 五个取样点里 **4 个命中 img**，只有右上角摸到角标。
 *   给图区 `z-index:0` 之后，img 的 z-index:1 只在自己内部生效，角标回到卡片层之上。 */
.pg-card-img{position:relative;z-index:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1;padding:8px;background:var(--surface);overflow:hidden}
/* `contain` 而不是 `cover`：cover 会把白底图四周的留白裁掉，商品直接顶着边框 ——
 * 那样图里自带的呼吸空间没了，白底图就必然糊成一片。
 * 🔴 图元素自己再挂一圈 1px 描边：`object-fit:contain` 只改绘制、不改元素尺寸
 *   （元素恒为内容盒 144×144），所以这圈线是**稳定的框**，与图里内容无关。
 *   它的作用是给「纯白底的图」一个确定边界 —— 白图与灰底的面积对比只有 1.11，
 *   靠颜色差看不出来，但 1px 细线在视觉上是「线」而不是「面」，1.15 就够辨认。 */
.pg-card-img img{position:relative;z-index:1;width:100%;height:100%;object-fit:contain;display:block;
  border:1px solid var(--line);border-radius:7px}
.pg-card-ph{position:absolute;inset:8px;display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--t5)}
.pg-card-bd{display:flex;flex-direction:column;gap:5px;padding:9px 10px 11px}
/* 行高 1.4 × 2 行 = 2.8em。原来写死 `min-height:34px`，而实际两行是 17.55×2 ≈ 35.1px
 * ⇒ 容器比内容少 1px，单行名称时卡片高度会矮一截（200 张里高度不齐很难看）。 */
.pg-card-nm{font-size:13px;font-weight:500;line-height:1.4;color:var(--t1);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.8em}
.pg-card-pr{font-size:14px;font-weight:600;color:var(--promo);line-height:1.2}
.pg-card-pr i{font-size:11px;font-weight:400;color:var(--t5);font-style:normal;margin-left:3px}
/* 角标（选中勾 / 已加 N）：两者都是**压在图片上**的标记，必须 `z-index:2`
 * （z-index:0 的图区之上；1 被 img 占了，写 2 语义更清楚，也给后续留了位置）。
 * 🔴 再挂一圈 `0 0 0 2px var(--canvas)` 的**白描边环**：白底图上蓝色圆盘有边界，
 *   深色图上白环把角标从背景里"挖"出来 —— 这是唯一在两种底色上都成立的做法，
 *   只靠「实心色块」必然在其中一种图上糊掉。
 * 🔴 位置 6px → 8px：与图区内距（padding:8px）对齐，视觉上与图块角对齐而不是浮在半空。 */
.pg-card-ck{position:absolute;top:8px;right:8px;z-index:2;width:20px;height:20px;border-radius:50%;
  background:var(--pri);color:#fff;font-size:12px;line-height:20px;text-align:center;
  box-shadow:0 0 0 2px var(--canvas),0 1px 3px rgba(15,23,42,.18)}
.pg-card-ct{position:absolute;top:8px;left:8px;z-index:2;background:var(--ink);color:#fff;font-size:11px;
  border-radius:999px;padding:1px 6px;line-height:1.4;box-shadow:0 0 0 2px var(--canvas)}
.pg-card.hide{display:none}
.pg-empty{padding:34px 0;text-align:center;font-size:13px;color:var(--t5)}
/* 吸底购买条：一次只出现**一个**数量 —— 这是整个版式能塞进 200 个 SKU 的关键。
 * sticky（不是 fixed）：抽屉/整页各有自己的滚动容器，fixed 会跑到遮罩之外。 */
/* 购买条：跟着主图排在左栏下方（掌柜 2026-10-24 指定）。
       * 宽度只有 1/3 列 ⇒ 竖排：已选规格 / 单价+包装+数量 / 合计 / 部门 / 三枚按钮。 */
/* 【2026-10-24 掌柜】购买区必须**是一个看得见的卡片**，与上方图片区分开：
 *   · 原来只有 `background:var(--canvas)`（纯白）+ `--sh1`（4% 阴影）且**没有 border** ——
 *     在浅色页面底上等于"白底上的白块"，四边都看不出边界；
 *   · 用户看到的那条"上边框灰线"其实是图片块（`.prod-img` 自带浅灰渐变底）的**底边**，
 *     不是本卡片的边框，所以左右下自然什么都没有。
 * 现在：1px 实边 + 更大圆角 + `--sh2`，与图片之间留 18px（由 `.pg-side` 的 gap 给）。
 * 🔴 间距别再用 margin-top：`.pg-side` 已经是 flex 列，margin 与 gap 会叠加成 28px。 */
.pg-bar{display:flex;align-items:center;flex-wrap:wrap;gap:8px 10px;padding:13px 14px 12px;
  background:var(--canvas);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh2)}
.pg-bar-sel{order:1;flex:1 1 100%;display:flex;flex-direction:column;gap:1px;min-width:0;max-width:none}
.pg-bar-h{font-size:11px;color:var(--t5)}
.pg-bar-sel b{font-size:14px;font-weight:500;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pg-bar-price{order:2;flex:0 0 auto;display:flex;align-items:baseline;gap:4px}
.pg-bar-price .p{font-size:18px;font-weight:600;color:var(--promo)}
.pg-bar-price .n{font-size:11px;color:var(--t5)}
/* 合计行兼作「选择区 / 金额区」的分界：卡片里如果只有间距，规格名、单价、合计、按钮会糊成一片。
 * 🔴 分隔线画在 `.pd-sum` 上而不是 `.pg-bar-sel` 上：后者在 ≤1240 会被 `max-width:150px` 收窄，
 *   那时线只剩 150px 一小截，比不画更难看；`.pd-sum` 恒为 `flex:1 1 100%`，任何宽度都横贯。 */
.pg-bar .pd-sum{order:5;margin:0;flex:1 1 100%;min-width:0;border-top:1px solid var(--line3);padding-top:9px}
/* 三枚按钮：窄栏里保持「两枚等分 + 收藏按内容宽」，与标准详情页同一比例。 */
.pg-bar .pd-acts{order:7;flex:1 1 100%;display:grid;grid-template-columns:1fr 1fr auto;gap:8px}
.pg-bar .pd-acts .btn{flex:1 1 auto;white-space:nowrap}
/* 包装档 / 部门：复用标准版的 DOM（#pd-pk-blk / input[name="d-pd"] 必须还在，
 * 否则 pdPkNow() 与 addcart 读不到 ⇒ 包装档丢失、部门归属变「未指定」），只把外壳压扁成胶囊。 */
.pg-bar-pk{order:3}
.pg-bar-pk .pd-blk-h,.pg-bar-pk .pd-pk-tip{display:none}
.pg-bar-pk .pd-blk{padding:0;margin:0;border:0;background:transparent}
.pg-bar-pk .pd-pk-list{display:flex;gap:6px;flex-wrap:nowrap}
.pg-bar-dept{order:6;flex:1 1 100%;max-width:none}
.pg-bar-dept .dept-mod-h{display:none}
.pg-bar-dept .dept-mod{padding:0;margin:0;border:0;background:transparent}
/* 部门 chips 必须**换行**、不能横向滚动：吸底条是窄条，滚动条会被裁在盒子边缘，
 * 看起来像按钮被切掉（实测 1440 下第三个部门正好被切）。 */
.pg-bar-dept .dp-pick-list{display:flex;gap:6px;flex-wrap:wrap;overflow:visible}
.pg-bar>.stepper{order:4;margin-left:auto}
.pg-bar-dept .dp-pick{padding:4px 9px;border-radius:999px;white-space:nowrap}
@media (max-width:1240px){
  .pg-cols{grid-template-columns:minmax(0,300px) minmax(0,1fr);column-gap:18px}
  .pg-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
  .pg-bar-sel{max-width:150px}
}
@media (max-width:900px){
  /* 🔴 必须是 minmax(0,1fr) 不能写成 1fr：`1fr` = `minmax(auto,1fr)`，单列的 auto 最小宽度
   * 会被吸底条里那串 nowrap 内容（单价 + 包装 chip + 步进器）顶开 ⇒ 整页横向溢出，
   * 手机上表现为「右边一列卡片被切掉」（实测 420 宽）。 */
  .pg-cols{grid-template-columns:minmax(0,1fr);row-gap:12px}
  .pg-side{position:static;max-height:none;overflow:visible}
  /* 🔴 必须显式 `width:100%`：`.pg-side` 是纵向 flex 容器，而 `margin:0 auto` 会**取消**
   *   交叉轴上的 stretch ⇒ 宽度退化成 fit-content（实测塌到 145px，只有图片自身宽度），
   *   `max-width:320px` 根本轮不到生效。写死 width 之后才是「撑满 → 被 320 截断 → 居中」。 */
  .pg-hero{width:100%;max-width:320px;margin:0 auto}
  .pg-grid{grid-template-columns:repeat(auto-fill,minmax(132px,1fr))}
  /* 窄屏不再吸底：吸底条里要塞 数量 / 包装 / 部门 / 合计 / 三枚按钮，一旦换行就会长到
   * 170px 以上，把卡片盖掉半屏（实测 800 宽）。改为跟着宫格排在末尾，滚到底即可见。 */
  .pg-bar{position:static;gap:10px;padding:10px 12px}
  .pg-bar .pd-sum{flex:1 1 100%;order:5;min-width:0}
}
@media (max-width:560px){
  .pg-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .pg-card-nm{font-size:12px}
  .pg-tools{gap:6px}
  .pg-cnt{margin-left:0}
  .pg-q{flex:1 1 100%}
  .pg-bar-sel,.pg-bar-price{max-width:none}
  .pg-bar-dept{max-width:none}
  .pg-bar .pd-acts{width:100%}
}

/* ==================================================================
 * 十九、2026-10-25 购物车 v2（地址前置 · 留言交货右上）
 * ==================================================================
 * 经掌柜 17:32 确认的设计稿：Ardot 740179665026190 页「v2 · 地址前置」。
 * 结构：
 *   .cart-layout
 *     ├ .cart-main  [ .addr-card + .items-card ]
 *     └ .cart-side  [ .side-card(交货与备注) + .price-card ]
 * 🔴 与 base.css §11b 的关系：那一段把 `.cart-layout` 定成单列、并给
 *   `.submit-card/.sc-grid` 一组三列栅格 —— 那是 **checkout.js（立即下单页）**在用的，
 *   **不要删**。本节用同选择器 + 后加载覆盖，只作用于购物车页。
 * 🔴 宽度是算出来的：1440 视口 `.content` 内宽 1344 → 减右栏 380 与 gap 20 → 左栏 944；
 *   表格 6 列固定宽合计 552，剩余 352 全给「商品信息」列。
 *   右栏一加宽，商品名就跟着变窄，改宽度前先重算这个和。
 * 🔴 sticky **只挂 .price-card**，不挂整个 .cart-side：右栏两张卡共约 600px，
 *   整体 sticky 在矮屏（内容区 <640px）会把底部的提交按钮裁到看不见 —— 那是最该看见的按钮。
 *   配套：`.cart-side` 用 align-self:stretch 撑满整行，价格卡才有可粘的余量。
 */

/* ---------- 19.1 骨架 ---------- */
.shell.hc-c .cart-layout{
  display:grid;grid-template-columns:minmax(0,1fr) 380px;
  gap:20px;align-items:start;
}
.shell.hc-c .cart-main{display:flex;flex-direction:column;gap:16px;min-width:0}
.shell.hc-c .cart-side{display:flex;flex-direction:column;gap:16px;min-width:0;align-self:stretch}
.shell.hc-c .cart-side > .card + .card{margin-top:0}
.shell.hc-c .side-card{padding:18px 20px;border-radius:18px}

/* ---------- 19.2 地址详情卡（地址 + 收货人 + 电话 = 一个整体）---------- */
.shell.hc-c .addr-card{padding:18px 20px;border-radius:18px}
.shell.hc-c .ac-view{display:flex;align-items:flex-start;gap:14px;min-width:0}
/* 🔴 两个视图同时在 DOM 里，只切 display：折叠时 #f-addr / #f-phone 仍在，
 *   否则提交取不到地址（见视图层注释）。 */
.shell.hc-c .addr-card.is-editing .ac-view{display:none}
.shell.hc-c .ac-edit{display:none}
.shell.hc-c .addr-card.is-editing .ac-edit{display:block}
.shell.hc-c .ac-pin{
  flex:0 0 36px;width:36px;height:36px;border-radius:10px;
  background:var(--pri-weak);color:var(--warn-ink);
  display:flex;align-items:center;justify-content:center;
}
.shell.hc-c .ac-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:6px}
.shell.hc-c .ac-addr{font-size:16px;font-weight:600;color:var(--ink);line-height:1.45;word-break:break-word}
.shell.hc-c .ac-person{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:13px;color:var(--t3)}
.shell.hc-c .ac-person b{font-weight:600;color:var(--t2)}
.shell.hc-c .ac-sep{color:var(--t5)}
.shell.hc-c .ac-def{
  flex:0 0 auto;display:inline-flex;align-items:center;height:20px;padding:0 8px;
  border-radius:999px;background:var(--ok-weak);color:var(--ok-ink);font-size:11px;font-weight:600;
}
.shell.hc-c .ac-ops{display:flex;align-items:center;gap:16px;margin-top:2px}
.shell.hc-c .ac-ops .link{font-size:12px}
.shell.hc-c .ac-link2{font-size:12px;color:var(--t4)}
.shell.hc-c .ac-link2:hover{color:var(--pri)}
.shell.hc-c .ac-ent{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
  height:26px;padding:0 12px;border-radius:999px;background:var(--sf);
  font-size:11px;color:var(--t4);white-space:nowrap;
}
.shell.hc-c .ac-ent b{font-weight:600;color:var(--t1)}
/* 展开态：电话占满、收货人只读 200 */
.shell.hc-c .ac-edit .field{margin-bottom:12px}
.shell.hc-c .ac-edit-row{display:flex;gap:12px;align-items:flex-start}
.shell.hc-c .ac-f-phone{flex:1 1 auto;min-width:0}
.shell.hc-c .ac-f-who{flex:0 0 200px}
.shell.hc-c .ac-sub{font-style:normal;font-size:11px;color:var(--t5);margin-left:4px}
.shell.hc-c .ac-ro{
  height:38px;display:flex;align-items:center;padding:0 12px;border-radius:8px;
  background:var(--sf);color:var(--t2);font-size:13px;
}
.shell.hc-c .ac-edit-ops{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}
/* 自定义按钮类：刻意**不**用 `btn ghost sm` 那串 —— tpl-smoke 用整页字符串断言它必须消失 */
.shell.hc-c .ac-btn{
  height:32px;padding:0 18px;border-radius:999px;font-size:13px;font-weight:500;
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  border:1px solid transparent;transition:background .15s,border-color .15s;
}
.shell.hc-c .ac-btn.ghost{background:var(--canvas);border-color:var(--line2);color:var(--t2)}
.shell.hc-c .ac-btn.ghost:hover{background:var(--sf)}
.shell.hc-c .ac-btn.pri{background:var(--pri-action);color:var(--on-action);font-weight:700}

/* ---------- 19.3 商品明细卡 ---------- */
.shell.hc-c .items-card{padding:0;border-radius:18px;overflow:hidden}
.shell.hc-c .items-hd{display:flex;align-items:center;gap:10px;padding:14px 20px;min-width:0}
.shell.hc-c .items-t{flex:0 0 auto;font-size:15px;font-weight:700;color:var(--ink)}
.shell.hc-c .items-cnt{flex:0 0 auto;font-size:12px;color:var(--t4)}
.shell.hc-c .items-sp{flex:1 1 auto;min-width:0}
/* 模板入口紧凑化：白卡 → 一行轻量入口。四态文案一个不少（tpl-smoke 18a–18e 钉着） */
.shell.hc-c .tpl-entry-mini{
  display:inline-flex;align-items:center;gap:8px;min-width:0;
  flex:0 0 auto;
  padding:0;background:none;border:0;box-shadow:none;border-radius:0;
}
.shell.hc-c .tpl-entry-mini .tpl-entry-ic{
  flex:0 0 20px;width:20px;height:20px;border-radius:6px;
  display:flex;align-items:center;justify-content:center;
  background:var(--pri-weak);color:var(--warn-ink);
}
.shell.hc-c .tpl-entry-mini .tpl-entry-ic svg{width:13px;height:13px}
.shell.hc-c .tpl-entry-mini .tpl-entry-nm{font-size:12px;font-weight:600;color:var(--t2);white-space:nowrap}
.shell.hc-c .tpl-entry-mini .tpl-entry-mt{
  font-size:11px;color:var(--t5);max-width:220px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.shell.hc-c .tpl-entry-mini .tpl-entry-src{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;height:20px;padding:0 8px;
  border-radius:999px;background:var(--pri-weak);color:var(--warn-ink);
  font-size:11px;font-weight:600;white-space:nowrap;
}
.shell.hc-c .tpl-entry-mini .tpl-entry-src a{cursor:pointer;font-weight:700;padding:0 2px;color:inherit}
.shell.hc-c .tpl-entry-mini .tpl-entry-ops{display:flex;align-items:center;gap:12px;margin-left:4px}
.shell.hc-c .tpl-entry-mini .tpl-entry-ops .link{
  font-size:12px;background:none;border:0;padding:0;cursor:pointer;
}
.shell.hc-c .tpl-entry-mini .tpl-mini-dim{color:var(--t4);font-weight:400}
.shell.hc-c .tpl-entry-mini .tpl-mini-dim:hover:not(:disabled){color:var(--pri)}
.shell.hc-c .tpl-entry-mini .tpl-mini-dim:disabled{color:var(--t5);cursor:not-allowed}

/* 表格：6 列口径，与卡片边缘齐平（表头浅底通铺，不再是内嵌的圆角盒） */
.shell.hc-c .items-card .tbl-wrap{
  padding:0;border-radius:0;background:none;box-shadow:none;
}
.shell.hc-c .items-card .cart-tbl{table-layout:fixed;width:100%;min-width:752px}
.shell.hc-c .items-card .cart-tbl th,
.shell.hc-c .items-card .cart-tbl td{padding-left:14px;padding-right:14px}
.shell.hc-c .items-card .cart-tbl th:first-child,
.shell.hc-c .items-card .cart-tbl td:first-child{padding-left:20px}
.shell.hc-c .items-card .cart-tbl th:last-child,
.shell.hc-c .items-card .cart-tbl td:last-child{padding-right:20px}
.shell.hc-c .items-card .cart-tbl th{padding-top:10px;padding-bottom:10px;background:var(--sf);font-weight:500;color:var(--t4)}
.shell.hc-c .items-card .cart-tbl td{padding-top:14px;padding-bottom:14px;border-top:1px solid var(--line5)}
.shell.hc-c .items-card .cart-tbl tbody td[data-act="row-hold"]{cursor:auto}
.shell.hc-c .items-card .cart-tbl tbody td[data-act="row-hold"] .qty-inp{cursor:text}

/* 商品信息列：缩略图 56 + 名称/编码两行 */
.shell.hc-c .items-card .cart-name{min-width:0;max-width:none;white-space:normal;word-break:break-word;line-height:1.45}
.shell.hc-c .cn-wrap{display:flex;align-items:center;gap:12px;min-width:0}
.shell.hc-c .cn-tx{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
.shell.hc-c .items-card .cart-name .nm{
  display:block;font-size:13px;font-weight:600;color:var(--t1);
  line-height:1.45;white-space:normal;overflow:visible;text-overflow:clip;
}
.shell.hc-c .items-card .cart-name .nm:hover{color:var(--pri-600);text-decoration:underline}
.shell.hc-c .cart-name .thumb{width:56px;height:56px;border-radius:10px;flex-shrink:0}
.shell.hc-c .items-card .nm-meta{font-size:11px;color:var(--t4);white-space:normal}
.shell.hc-c .items-card .nm-meta .cart-oc{color:var(--t4);font-variant-numeric:tabular-nums}
.shell.hc-c .items-card .nm-pre{margin-top:1px}
.shell.hc-c .cart-dept-inline{margin-top:4px;display:flex}
/* 规格 / 单价·单位 / 小计 / 操作 */
.shell.hc-c .items-card .cart-spec{white-space:normal}
.shell.hc-c .items-card .cart-spec .sp-tag{white-space:normal;font-size:11.5px}
.shell.hc-c .items-card .cart-price{text-align:right}
.shell.hc-c .items-card .cart-price .num{font-size:13px;color:var(--t1)}
.shell.hc-c .items-card .cart-price .pu{font-size:11px;color:var(--t4);margin-top:1px}
.shell.hc-c .items-card .cart-am{text-align:right}
.shell.hc-c .items-card .cart-am .num{font-size:14px;font-weight:700;color:var(--promo)}
.shell.hc-c .items-card .ops a{display:block;line-height:1.7}
.shell.hc-c .items-card .ops a.danger{color:var(--promo)}
/* 步进器收一档：24+4+44+4+24 = 100，正好塞进 132px 列（去掉左右内距 28） */
.shell.hc-c .items-card .cart-tbl .stepper button{width:24px}
.shell.hc-c .items-card .cart-tbl .stepper b{width:44px}
.shell.hc-c .cart-empty{text-align:center;padding:48px;color:var(--t4);white-space:normal}

/* 表尾：清空购物车 ｜ 共 N 项 · 合计 ¥X */
.shell.hc-c .items-card .cart-foot{
  display:flex;align-items:center;gap:12px;
  padding:14px 20px;border-top:1px solid var(--line5);background:var(--canvas);
}
.shell.hc-c .items-card .cart-foot .cf-r{margin-left:auto;display:flex;align-items:baseline;gap:10px}
.shell.hc-c .items-card .cart-foot .cf-cnt{font-size:12px;color:var(--t4)}
.shell.hc-c .items-card .cart-foot .cf-cnt b{color:var(--t1)}
.shell.hc-c .items-card .cart-foot .cf-amt{font-size:16px;font-weight:700;color:var(--promo);font-variant-numeric:tabular-nums}

/* ---------- 19.4 右栏 · 交货与备注 ---------- */
.shell.hc-c .side-hd{display:flex;align-items:center;gap:8px;margin-bottom:14px}
.shell.hc-c .side-hd b{font-size:15px;font-weight:700;color:var(--ink)}
.shell.hc-c .side-hd-o{margin-left:auto;font-size:11px;color:var(--t4)}
.shell.hc-c .side-card .field{margin-bottom:14px}
.shell.hc-c .side-card .field:last-child{margin-bottom:0}
.shell.hc-c .side-card #f-note{min-height:64px;resize:vertical}
/* ---------- 19.5 右栏 · 价格明细 ---------- */
.shell.hc-c .price-card{position:sticky;top:12px}
.shell.hc-c .price-rows{
  display:flex;flex-direction:column;gap:10px;
  padding-bottom:16px;border-bottom:1px solid var(--line4);
}
.shell.hc-c .price-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;font-size:12px;color:var(--t4)}
.shell.hc-c .price-row b{font-size:13px;font-weight:400;color:var(--t1)}
.shell.hc-c .price-row .price-fee{font-size:12px;color:var(--warn-ink)}
.shell.hc-c .price-row .price-dim{font-size:12px;color:var(--t4)}
.shell.hc-c .price-row .price-warn{font-size:12px;color:var(--warn-ink)}
.shell.hc-c .price-total{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding-top:16px}
.shell.hc-c .price-total > span{font-size:13px;font-weight:600;color:var(--t1)}
/* 合计走 --promo（#C2261B），与表尾 .cf-amt 同一支令牌 —— 用 --err-ink 会「两个红」 */
.shell.hc-c .side-sum-amt{
  font-size:24px;line-height:1.1;font-weight:700;color:var(--promo);
  font-variant-numeric:tabular-nums;letter-spacing:-.3px;
}
.shell.hc-c .side-submit{width:100%;height:48px;margin-top:18px;font-size:15px;font-weight:700}
.shell.hc-c .side-hint{margin-top:8px;font-size:11px;line-height:1.5;color:var(--t4)}

/* ---------- 19.6 窄屏折叠：单列，右栏下沉 ----------
 * 🔴 断点沿用既有档位 1366（本仓只有 1366/1240/1080/900/560 五档，
 *   由 test/responsive-breakpoint-smoke.js 的白名单钉死，新造数字会被判「口径碎片化」）。 */
@media (max-width:1366px){
  .shell.hc-c .cart-layout{grid-template-columns:minmax(0,1fr)}
  /* 单列时右栏别再纵向堆两张全宽卡 —— 改成自适应栅格，宽了自动降成两列/一列 */
  .shell.hc-c .cart-side{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px}
  .shell.hc-c .price-card{position:static}
}

/* ==================================================================
 * 二十、2026-10-26 参数表版（客户端详情页第三种版式 · products.disp === 'param'）
 * ----------------------------------------------------------------
 * 定位：同一个链接里那批商品的**第三种排法** ——
 *   标准详情页 = 属性值列表 ／ 宫格页 = 一件一卡 ／ 本版 = 一行一件。
 * 不动的：标准页与宫格页的规则**一个字没改**（本版选择器全部挂在 .pp-* 下）。
 * 🔴 三处只能靠父级作用域覆盖，**不要往行上加类**：
 *   ① 行的 class 字面量 `class="pd-sku-row"` 是 cdrawer-smoke 数行数的 token；
 *   ② `.pd-sku-row` 的既有 flex 布局仍要给标准页用 ⇒ 这里用
 *      `.pp-tbl .pd-sku-row{display:grid}` 覆盖，靠选择器权重取胜；
 *   ③ `.pd-sku-row.sel`（已填数量）与 `.pd-sku-row.on`（点行预览）**沿用既有视觉**，
 *      不重写 —— 两个版式对"选中"的表达必须一致，否则同一个客户会以为操作没生效。
 * 🔴 内容面一律用 1px 真边框（`var(--line2)`），不用 `--sh1` 之外的外投影；
 *   本页唯一允许的投影是左栏成交条的 `--sh1`（它本来就是 0 0 0 1px 描边环）。
 * ================================================================== */
.pp-wrap{min-width:0}
.pp-cols{display:grid;grid-template-columns:360px minmax(0,1fr);gap:20px;align-items:start}
/* 左栏整列跟随滚动：主图 / 当前款维度 / 包装 / 批量条始终在视野里 ——
 * 客户在右侧表格里往下翻 200 行时，左边还看得见"我现在选的是哪一款、一共多少钱"。 */
.pp-side{position:sticky;top:12px;align-self:start;display:flex;flex-direction:column;gap:12px;min-width:0}
.pp-main{min-width:0}
.pp-box{background:var(--canvas);border-radius:var(--r-md);box-shadow:var(--sh1);padding:14px 16px 16px}
.pp-box .page-head{margin-bottom:10px}
/* ---------- 筛选区 ---------- */
.pp-tools{background:var(--sf);border-radius:var(--r-sm);padding:8px 8px 6px;margin-bottom:12px}
.pp-q-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.pp-q{flex:1 1 auto;min-width:120px;height:32px;border:1px solid var(--line2);border-radius:var(--r-sm);
  padding:0 10px;font-size:13px;color:var(--t1);background:var(--canvas)}
.pp-q:focus{outline:none;border-color:var(--pri)}
.pp-cnt{font-size:12px;color:var(--t5);white-space:nowrap;font-variant-numeric:tabular-nums}
.pp-cnt b{color:var(--t2);font-weight:600}
/* 每个维度一行：维度名固定宽度 + chips 自动换行。
 * 🔴 维度名必须 truncate（采集来的维度名有「垫圈外径（适用于 GB/T97.1）」这种长串），
 *   给固定 60px 会把 chips 挤到第二行、8 个维度就把表格推到首屏之外。 */
.pp-grps{display:flex;flex-direction:column;gap:6px}
.pp-grp{display:flex;align-items:flex-start;gap:8px;min-width:0}
.pp-grp-h{flex:0 0 64px;font-size:12px;line-height:22px;color:var(--t4);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.pp-chips{display:flex;flex-wrap:wrap;gap:6px;min-width:0;flex:1 1 auto}
/* chip = 「值 + 剩余可选数」两个数。工业品靠数字决策，所以数字必须有、且要能扫读。 */
.pp-chip{display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 8px;
  border:1px solid var(--line2);border-radius:999px;background:var(--canvas);
  font-size:12px;line-height:1;color:var(--t2);cursor:pointer;font-variant-numeric:tabular-nums;
  transition:border-color .12s,background-color .12s,color .12s}
.pp-chip i{font-style:normal;font-size:11px;color:var(--t5);font-variant-numeric:tabular-nums}
.pp-chip:hover{border-color:var(--pri-200);color:var(--t1)}
.pp-chip.on{border-color:var(--pri);background:var(--pri-weak);color:var(--t1)}
.pp-chip.on i{color:var(--t3)}
/* 该值在当前其它条件下匹配 0 款 ⇒ 置灰不可点。
 * 🔴 不能用 display:none 藏掉：客户会以为"这个尺寸不存在"，而实际是"这套条件里没有"。
 *   留着 + 数字写 0，他才好退回上一个条件。 */
.pp-chip.off{color:var(--t5);border-color:var(--line3);cursor:not-allowed;background:var(--canvas)}
.pp-chip.off i{color:var(--t5)}
.pp-grpm{align-self:flex-start;height:22px;padding:0 10px;margin-left:72px;border:1px dashed var(--line2);
  border-radius:999px;background:transparent;font-size:12px;color:var(--t3);cursor:pointer}
.pp-grpm:hover{border-color:var(--pri-200);color:var(--t1)}
/* 维度名后的取值总数：295 个取值时客户得知道「这只是前 12 个」，否则会以为筛选器就这么多。 */
.pp-grp-h b{display:inline-block;margin-left:4px;font-size:11px;color:var(--t5);font-weight:400;
  font-variant-numeric:tabular-nums}
/* 组内的「还有 N 个取值」：与维度级的「+ N 个筛选条件」同为 .pp-grpm，但语义不同 ——
 * 前者嵌在 chips 行里（跟着最后一个 chip），后者独占一行。靠 pp-grpm-v 区分。 */
.pp-grpm-v{margin-left:0;color:var(--t4)}
.pp-selbar{display:flex;align-items:center;gap:10px;margin-top:8px;padding-top:7px;border-top:1px dashed var(--line2);
  font-size:12px;color:var(--t4)}
.pp-selbar b{color:var(--t1);font-weight:600}
.pp-clear{margin-left:auto;height:22px;padding:0 10px;border:1px solid var(--line2);border-radius:999px;
  background:var(--canvas);font-size:12px;color:var(--t3);cursor:pointer}
.pp-clear:hover{border-color:var(--pri);color:var(--t1)}
/* ---------- 参数表 ----------
 * 列模板由 JS 整串传进 `--pp-gtc`：`grid-template-columns` 可以吃变量，
 * 但 `repeat()` 的**计数位不许用变量**（写了会被整条声明丢弃、表格塌成单列且不报错）
 * ⇒ 变量只能挂在整个属性值上，不能挂在重复次数上。 */
.pp-tbl{--pp-gtc:34px 52px minmax(150px,340px) minmax(70px,120px) minmax(70px,120px) minmax(70px,120px) 88px 80px 112px;
  /* 🔴 `width:fit-content` + `max-width:100%`：列宽都有上限，撑满容器会让剩余空间留在**表格内部**
   *   （实测单维度 6 列时数量列飘到中间、右侧 240px 空带，看着像列没对齐）。
   *   让表格按内容收缩，用不完的空间就变成卡片自己的留白。多维时总宽超容器 ⇒ max-width 兜底，
   *   列被 minmax 下限压回、必要时横向滚动。 */
  width:fit-content;max-width:100%;
  overflow-x:auto;border:1px solid var(--line2);border-radius:var(--r-sm)}
.pp-head,.pp-tbl .pd-sku-row{display:grid;grid-template-columns:var(--pp-gtc);align-items:center;gap:0}
.pp-head{height:36px;background:var(--sf);border-bottom:1px solid var(--line2);
  font-size:11.5px;color:var(--t4);font-weight:600;white-space:nowrap}
.pp-c{min-width:0;padding:0 6px}
.pp-c-ck{display:flex;align-items:center;justify-content:center;padding:0}
.pp-c-th{display:flex;align-items:center;justify-content:center;padding:0}
.pp-c-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pp-c-d{font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pp-c-pr{font-variant-numeric:tabular-nums;white-space:nowrap}
.pp-c-st{white-space:nowrap}
.pp-c-q{display:flex;align-items:center;justify-content:flex-end;padding-right:14px}
/* 行：覆盖标准页的 flex，改成与表头同一套 grid。
 * 🔴 行高定死 52px —— 让 200 行的表能扫读；不定高的话名称两行与单行会混排成锯齿。 */
.pp-tbl .pd-sku-row{height:52px;padding:0;border-bottom:1px solid var(--line3);cursor:pointer;
  background:var(--canvas);transition:background-color .1s}
.pp-tbl .pd-sku-row:last-of-type{border-bottom:none}
.pp-tbl .pd-sku-row:hover{background:var(--sf)}
/* 点行预览：蓝框 + 淡蓝底。视觉沿用宫格页 `.pg-card.on` 的同一套语义（描边 1px + inset 环）。 */
.pp-tbl .pd-sku-row.on{background:var(--pri-weak);box-shadow:inset 0 0 0 1px var(--pri)}
/* 缺货行：整行文字降一档对比（型号与维度值），单价位改成「询价」。
 * 🔴 只降文字、不降整行 opacity —— 降 opacity 会让「缺货·可询」徽章一起变淡，
 *   而那个徽章恰恰是客户要先看清的东西。 */
.pp-tbl .pd-sku-row[data-pre="1"] .pp-c-nm,
.pp-tbl .pd-sku-row[data-pre="1"] .pp-c-d{color:var(--t4)}
.pp-ask{font-style:normal;color:var(--t4);font-size:12.5px}
.pp-pu{font-style:normal;font-size:11px;color:var(--t5);margin-left:2px}
/* 勾选圈：22×22 的圆环，勾选态 = 数量 > 0（`.sel` 由 UI_skuSum 维护）——
 * 这里**不复用 <input type="checkbox">**：真正的勾选状态在数量上，
 * 用原生 checkbox 会出现「勾了但数量为 0 / 数量填了却没勾」两套真相。 */
.pp-ck{width:18px;height:18px;padding:0;border:1.5px solid var(--line2);border-radius:5px;
  background:var(--canvas);cursor:pointer;position:relative;flex:0 0 auto}
.pp-ck:hover{border-color:var(--pri)}
.pp-tbl .pd-sku-row.sel .pp-ck{border-color:var(--pri);background:var(--pri)}
.pp-tbl .pd-sku-row.sel .pp-ck::after{content:"";position:absolute;left:5px;top:1.5px;width:5px;height:9px;
  border:solid var(--canvas);border-width:0 1.8px 1.8px 0;transform:rotate(42deg)}
.pp-allck{height:22px;padding:0 6px;border:1px solid var(--line2);border-radius:var(--r-sm);
  background:var(--canvas);font-size:11px;color:var(--t3);cursor:pointer;white-space:nowrap}
.pp-allck:hover{border-color:var(--pri);color:var(--t1)}
/* 缩略图：40×40 圆角块。无图时用首字垫底（与宫格页同一手法：空白方块分不清谁是谁）。 */
.pp-c-th img{width:40px;height:40px;object-fit:contain;border-radius:8px;background:var(--surface);display:block}
.pp-th-ph{width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:8px;
  background:var(--surface);color:var(--t5);font-size:14px}
/* 数量列：把标准页那套步进器缩一档，塞进 96px 的列。
 * 🔴 只改尺寸，**不动它的 id / data-act**（`sku-step` 与 `.pd-qty` 是加购与合计的唯一契约）。 */
.pp-c-q .stepper{width:88px;height:26px}
.pp-c-q .stepper button{width:22px;font-size:13px}
.pp-c-q .stepper b{min-width:0;flex:1 1 auto}
.pp-c-q .pd-qty{width:100%;text-align:center;font-size:12.5px;padding:0}
/* 表尾：加载提示 / 到底提示。grid 容器里必须横跨整行，否则会挤进第一列。 */
.pp-foot{grid-column:1/-1;height:40px;display:flex;align-items:center;justify-content:center;
  font-size:12px;color:var(--t5);border-top:1px solid var(--line3);background:var(--canvas)}
/* ---------- 左栏 ---------- */
/* 当前款的全部维度值：两列网格，键灰值黑。
 * （设计稿这里是尺寸剖面图；剖面图要求"内径/外径/厚度"三个固定维度名，
 *   而实际商品维度名千差万别 —— 换成等价且任何品类都能用的逐条列出。） */
.pp-curdims{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--canvas);
  border-radius:var(--r-sm);box-shadow:var(--sh1);overflow:hidden}
.pp-cd{display:flex;flex-direction:column;gap:2px;padding:7px 10px;background:var(--canvas);min-width:0}
.pp-cd-k{font-size:11px;color:var(--t5);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pp-cd-v{font-size:13px;color:var(--t1);font-weight:500;font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pp-side-pk .pd-blk{padding:10px 12px}
/* 批量条：合计 + 部门 + 两个按钮，与宫格页吸底条同构（id 与 data-act 逐个复用标准页契约）。 */
.pp-bar{display:flex;flex-direction:column;gap:9px;padding:12px;background:var(--canvas);
  border-radius:var(--r-md);box-shadow:var(--sh1)}
.pp-bar-dept .dept-mod-h{font-size:11px}
.pp-bar .pd-sum{margin:0}
.pp-bar .pd-buy-line{display:flex;gap:8px}
.pp-bar .pd-buy-line .btn{flex:1 1 auto;min-width:0;white-space:nowrap}
/* 窄屏：左栏收成静态、单列堆叠（否则 360px 的左栏会把表格压到只剩 600px）。 */
@media (max-width:1366px){
  .pp-cols{grid-template-columns:1fr}
  .pp-side{position:static}
  .pp-curdims{grid-template-columns:1fr 1fr}
}
@media (max-width:900px){
  .pp-box{padding:12px}
  .pp-grp-h{flex:0 0 52px}
  .pp-grpm{margin-left:60px}
  .pp-curdims{grid-template-columns:1fr}
}
.shell.hc-c .cart-eta{margin-left:8px;font-size:11.5px;color:var(--t3);white-space:nowrap}
