/* ==========================================================================
   产品详情页（/products/<slug>）
   面包屑 / 图库 / 概要 / 商务信息 / 阶梯价 / 规格表 / 报价说明
   ========================================================================== */

/* ---------- 主布局：左栏（图库 + 定制声明 + CTA）/ 右栏（标题→认证→价格→加购）
   ★ 2026-10-12 第 29 轮重排：右栏 1162px → 约 990px，左栏 648px → 约 820px。
     动因是实测左右高度差 1.8 倍，右侧信息过载、左侧图库下方大片空白。
   窄屏（≤860px）单栏堆叠，见文件末尾媒体查询。 ---------- */
.pd-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}

/* ---------- 图库 ---------- */
/* .pd-media / .pd-summary 是 pd-layout 的两个网格子项。
   它们自身不用额外声明（子元素已各自定义），这里只做最小约束：
   min-width:0 让长型号/长标题在网格里能正确换行，不会把列撑破。 */
.pd-media { min-width: 0; }
.pd-gallery { min-width: 0; }
.pd-summary { min-width: 0; }

/* 定制声明（OEM/ODM）：第 68 轮已迁出本栏，见 <section> 里的 .pd-oem__text。
   ⚠️ 两个 CTA 按钮**不在**这里 —— 业主随后要求缩小、挪到右侧加购区旁边
      （见下方的 .pd-buy__alts）。 */
.pd-gallery__main {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); overflow: hidden; color: var(--ink-3);
}

/* ---------- 图库轮播（第 68 轮）----------
   ★ 轨道用原生 overflow-x + scroll-snap，不自己算 transform：
     移动端滑动/惯性/键盘焦点全部免费，JS 只把「第几格」滚进视野。
   ★ 滚动条必须藏掉（三处都写：标准 / WebKit / 否则 Safari 下方多一条灰带）。 ---------- */
.pd-slides {
  display: flex;
  /* ★★★ 第 78 轮：不再用 `height: 100%`。
     那是一个"百分比高度依赖父级解析结果"的链条：父级高度由 `aspect-ratio` 算出，
     子级再按百分比取 —— 定制浏览器在图片加载 / 地址栏收缩这类重排时机上，
     可能把这一环算成 0，于是**图库整块瞬间塌陷几百 px**，滚动锚定为了
     "保持视口内容不动"就把页面拽回去（业主看到的就是"一滑窜回顶部"）。
     父级 `.pd-gallery__main` 是 `position: relative` + `aspect-ratio: 1/1`，
     这里直接铺满它，高度的来源就只剩一个，不会再抖。 */
  position: absolute; inset: 0;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;   /* 横滑到底别把整页带走 */
  scrollbar-width: none;
}
.pd-slides::-webkit-scrollbar { display: none; }

.pd-slide {
  flex: 0 0 100%; width: 100%; height: 100%; min-width: 0;
  display: flex; align-items: center; justify-content: center;
  scroll-snap-align: center;
  scroll-snap-stop: always;          /* 一次只翻一格，图多时不会"飞过头" */
}
.pd-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 视频用 contain + 黑底：竖屏素材两侧留黑，比裁掉画面安全 */
.pd-slide--video { background: #0b0f14; }
.pd-slide__video { width: 100%; height: 100%; object-fit: contain; display: block; }
.pd-slide--empty { width: 100%; }

/* ---------- 缩略图条 + 两侧箭头（第 68 轮追加）----------
   ★ 箭头**不压在大图上**（业主：大图区别挡东西），而是缩略图一行的左右两端。
     所以这里不再用 position:absolute —— 三个元素都是 flex 子项，
     缩略图条 flex:1 吃掉剩余宽度，箭头固定 32px。
   ★ 逻辑方向：RTL 时第一颗缩略图从右开始，箭头 data-dir 的语义不变
     （JS 用 direction 换算位移），DOM 顺序仍是「前 · 条 · 后」。 */
.pd-strip {
  display: flex; align-items: center; gap: 8px;
  margin-block-start: 12px;
}
.pd-nav {
  flex: 0 0 auto;
  width: 32px; height: 32px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; cursor: pointer;
  color: var(--primary);
  background: rgba(255, 255, 255, .62);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: .85;
  transition: opacity .15s, background-color .15s, border-color .15s, transform .15s;
}
.pd-nav:hover {
  opacity: 1; background: var(--primary-soft); border-color: var(--primary);
}
/* 修饰类负责与缩略图条的呼吸：gap 是 8px，这里各收 2px，视觉上不会显得箭头离图太远 */
.pd-nav--prev { margin-inline-end: 2px; }
.pd-nav--next { margin-inline-start: 2px; }
.pd-nav:active { transform: scale(.94); }
.pd-nav:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* 张数指示 1 / 8：右下角，深色半透明，压在白图和暗图上都读得清 */
.pd-count {
  position: absolute; inset-block-end: 10px; inset-inline-end: 10px;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(15, 23, 42, .45); color: #fff;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  pointer-events: none; z-index: 3;
}

/* 缩略图：**固定单行横滚**，绝不换行（第 68 轮业主：图多了别往下堆） */
.pd-thumbs {
  flex: 1 1 auto; min-width: 0;
  display: flex; gap: 10px;
  overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding-block: 2px;               /* 给焦点环留位置 */
  scrollbar-width: none;
}
.pd-thumbs::-webkit-scrollbar { display: none; }
.pd-thumb {
  position: relative;
  flex: 0 0 auto; width: 72px; height: 72px;
  padding: 0;
  border: 2px solid var(--line); border-radius: 10px;
  background: var(--bg); overflow: hidden; cursor: pointer;
  transition: border-color .15s;
  scroll-snap-align: start;
}
.pd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-thumb:hover,
.pd-thumb.is-active { border-color: var(--primary); }
.pd-thumb--video { background: #0b0f14; }
.pd-thumb__play {
  position: absolute; inset: 0; margin: auto;
  width: 26px; height: 26px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .82); color: #0b0f14;
  pointer-events: none;
}

/* ---------- 概要 ---------- */
.pd-model {
  display: inline-block; margin-block-end: 10px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  background: var(--bg-soft); color: var(--ink-2);
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
}
.pd-title {
  margin: 0 0 14px;
  font-size: clamp(22px, 3.2vw, 32px);
  line-height: 1.24;
}
.pd-lead {
  margin: 0 0 22px; color: var(--ink-2);
  font-size: 16px; line-height: 1.7;
}

/* ---------- 型号 + 认证同一行（2026-10-12 第 29 轮）----------
   原来认证徽章排在价格表之后、型号自己占一行，两条都被弱化。
   现在合并成一行紧跟标题，认证文字走主题色（业主指定）。
   注：「MOQ / 日产能」信息卡已整块删除 —— MOQ 从首档数量已能看出。 */
.pd-certrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-block: 0 20px;
}
.pd-certrow .pd-model { margin-block-end: 0; }
.pd-certrow__label { color: var(--primary); font-size: 13px; font-weight: 700; }
/* 认证徽章改用主题色，与「已认证」标签连成一个视觉组 */
.pd-certrow .cert-badge {
  background: var(--primary-soft); border-color: transparent;
  color: var(--primary); font-weight: 700;
}

.cert-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-block-start: 14px; }
.cert-badge {
  display: inline-block; padding: 6px 14px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft); border: 1px solid var(--line);
  font-size: .8125rem; font-weight: 600; color: var(--ink-2);
}

/* ---------- 产品说明：富文本（第 30 轮） ----------
   描述从「纯文本」升级为**白名单 HTML**（见 app/richtext.py），
   所以这里要为它允许的那批标签配齐样式：
   h3/h4 小标题、ul/ol 列表、figure/figcaption 图注、img/video 媒体、blockquote 引用。

   ⚠️ 两条纪律：
   1. 一律用**逻辑属性**（margin-block / padding-inline-start）——
      阿语 RTL 下自动镜像，不用维护第二套样式。
   2. 颜色只引 CSS 变量 —— 站点主色由后台注入，写死色值等于把换肤功能废掉。 */
.pd-desc { color: var(--ink); font-size: 16px; line-height: 1.85; }
.pd-desc > *:first-child { margin-block-start: 0; }
.pd-desc > *:last-child { margin-block-end: 0; }
.pd-desc p { margin-block: 0 1em; }

.pd-desc h3 {
  margin-block: 1.6em .6em;
  font-size: 1.25rem; line-height: 1.4; font-weight: 700;
}
.pd-desc h4 {
  margin-block: 1.4em .5em;
  font-size: 1.0625rem; line-height: 1.45; font-weight: 700; color: var(--ink-2);
}
.pd-desc strong { font-weight: 700; }
.pd-desc em { font-style: italic; }
.pd-desc u { text-decoration: underline; text-underline-offset: 3px; }
.pd-desc s { text-decoration: line-through; color: var(--ink-3); }

.pd-desc ul,
.pd-desc ol { margin-block: 0 1em; padding-inline-start: 1.5em; }
.pd-desc li { margin-block-end: .35em; }
.pd-desc li::marker { color: var(--primary); }

.pd-desc blockquote {
  margin-block: 0 1em; margin-inline: 0;
  padding-inline-start: 1em;
  border-inline-start: 3px solid var(--primary-border);
  color: var(--ink-2);
}

.pd-desc a { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }
.pd-desc a:hover { color: var(--primary-hover); }

.pd-desc img {
  display: block; max-width: 100%; height: auto;
  margin-block: 1.2em;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.pd-desc figure { margin-block: 1.2em; margin-inline: 0; }
.pd-desc figure img { margin-block: 0; }
.pd-desc figcaption {
  margin-block-start: .5em;
  font-size: .875rem; line-height: 1.6; color: var(--ink-3); text-align: center;
}
.pd-desc video {
  display: block; width: 100%; height: auto;
  margin-block: 1.2em;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--media-placeholder);
}

/* 可点击放大（JS 就绪后才加类；没 JS 时鼠标不会出现「可点」的假承诺） */
.pd-desc img.is-zoomable { cursor: zoom-in; }

/* ---------- 图片放大遮罩（灯箱） ---------- */
.pd-zoom {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--overlay);
}
/* ⚠️ 这条必须写：`.pd-zoom { display:flex }` 会压过 UA 的 `[hidden]{display:none}`，
   于是 hidden 设了也不生效、遮罩一直盖着页面（第 25 轮草稿横幅踩过同一个坑）。
   用属性选择器提高特异性，比"靠顺序"稳。 */
.pd-zoom[hidden] { display: none; }
.pd-zoom__img {
  max-width: 100%; max-height: 100%;
  border-radius: var(--radius-sm); background: var(--bg);
}
.pd-zoom__close {
  position: absolute; inset-block-start: 12px; inset-inline-end: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--tap-min); min-height: var(--tap-min);
  padding-inline: 12px;
  font-size: .875rem; font-weight: 600;
  color: var(--bg); background: transparent;
  border: 1px solid var(--ink-3); border-radius: var(--radius-pill);
  cursor: pointer;
}
.pd-zoom__close:hover { background: var(--ink-3); color: var(--bg); }
/* 遮罩打开时锁住页面滚动，否则背景会跟着滑（移动端尤其明显） */
body.is-zoom-open { overflow: hidden; }

/* ---------- 规格表 ---------- */
.spec-table {
  width: 100%; border-collapse: collapse;
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.spec-table tr + tr { border-block-start: 1px solid var(--line); }
.spec-table th,
.spec-table td {
  padding: 13px 16px; text-align: start; vertical-align: top;
  font-size: 14px; line-height: 1.6;
}
.spec-table th {
  width: 32%; background: var(--bg-soft);
  color: var(--ink-2); font-weight: 600; white-space: nowrap;
}
.spec-table td { color: var(--ink); }

/* ==========================================================================
   阶梯价格（数量区间 → 单价，统一 USD）
   ========================================================================== */
.pd-tiers {
  margin-block: 0 24px;
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--bg);
}
.pd-tiers__title {
  padding: 11px 16px; border-block-end: 1px solid var(--line);
  background: var(--bg-soft); color: var(--ink-2);
  font-size: 13px; font-weight: 700; letter-spacing: .01em;
}
.pd-tiers__fallback {
  margin: 0; padding: 14px 16px;
  color: var(--ink); font-size: 15px; font-weight: 600;
}

.tier-table { width: 100%; border-collapse: collapse; }
.tier-table thead th {
  padding: 9px 16px; text-align: start;
  border-block-end: 1px solid var(--line);
  color: var(--ink-3); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; white-space: nowrap;
}
.tier-table tbody tr + tr { border-block-start: 1px solid var(--line); }
.tier-table td {
  padding: 12px 16px; color: var(--ink);
  font-size: 14px; vertical-align: middle;
}
.tier-table tbody tr:hover { background: var(--bg-soft); }
/* 价格列右对齐更易比较 */
.tier-table th:last-child,
.tier-table td:last-child { text-align: end; }

.tier-price { white-space: nowrap; }
.tier-price > .ltr-value {
  color: var(--ink);
  font-size: 17px; font-weight: 700; letter-spacing: .01em;
}
.tier-remark {
  display: block; margin-block-start: 2px;
  color: var(--ink-3); font-size: 11.5px; font-weight: 500;
}
.pd-tiers__note {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  margin: 0; padding: 10px 16px;
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft); color: var(--ink-3);
  font-size: 12px; line-height: 1.6;
}

/* ==========================================================================
   采购动作区（数量 + 加入购物车 + 实时阶梯价提示）
   ⚠️ 2026-10-12 第 20 轮新增：详情页原来**没有加购入口**（只有 Get a Quote /
      WhatsApp），客户看完规格想下单找不到按钮，是漏斗漏点。此处补上，
     并把阶梯价接到按钮旁：改数量 → 立刻看到「这档单价 / 还差 N 件进下一档」。
   DOM:  .pd-buy > .pd-buy__form > (.pd-buy__row > .pd-buy__qty + .pd-buy__btn)
                                   > .pd-buy__hint > .pd-buy__moq
   ========================================================================== */
.pd-buy {
  margin-block: 18px 10px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}
.pd-buy__form { margin: 0; }

/* 数量 + 主按钮 + 次要动作**必须同一行**（2026-10-12 第 29 轮业主明确要求：
   Get a Quote 与 WhatsApp 图标要在 Add to cart 右边，不许掉到下一行）。
   ⚠️ 右栏可用宽度在 1100px 视口下只有约 476px，四件控件横排非常紧。
      关键一招：把「Quantity」标签改成**竖向叠在步进器上方**，
      一下省出约 70px 横向空间 —— 这样英文有余量，阿语也不换行。
      （试过保留横排标签 + 缩小尺寸：英文勉强够，阿语仍会折行。） */
.pd-buy__row {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px;
}
.pd-buy__qty {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 4px;
  margin: 0; /* label 默认有 margin */
}
.pd-buy__qty-label {
  color: var(--ink-2); font-size: .8125rem; font-weight: 600;
  white-space: nowrap;
}
/* 数量步进器：宽度收紧一档（40/56/40 = 136px），为同排的三个按钮腾地方；
   高度仍守 --tap-min（44px），与同排按钮齐平。
   ⚠️ 步进器外面还有一层 1px 边框，总高 46px，底部对齐后比按钮高 2px ——
      断言「同一行」时要用容差，不能要求 top 完全相等。 */
.pd-buy .qty-stepper button { width: 40px; min-height: var(--tap-min); font-size: 1.0625rem; }
/* 数量已到起订量时「−」被禁用 —— 必须看得出来，否则客户以为按钮坏了。
   ⚠️ 这里显式写 `.pd-buy` 前缀提高特异性：`.qty-stepper button:disabled`
   （在 40-page-cart.css）与 `.pd-buy .qty-stepper button` 特异性相同，
   靠"后导入者胜"太脆弱，不如直接给一条更专的。 */
.pd-buy .qty-stepper button:disabled,
.pd-buy .qty-stepper button:disabled:hover {
  color: var(--line);
  background: transparent;
  cursor: not-allowed;
}
.pd-buy .qty-stepper input { width: 56px; min-height: var(--tap-min); font-size: .9375rem; }

.pd-buy__btn { flex: 1 1 auto; white-space: nowrap; }

/* ---------- 次要动作：Get a Quote + WhatsApp 图标（2026-10-12 第 29 轮）----------
   业主：两个按钮「缩小，放在 add to cart 旁边」，且必须与加购按钮**同一行**；
   WhatsApp 用图标表示、颜色搭配要舒服。
   缩小 = 去掉 btn--lg（52px），回到 .btn 基线的 44px 触控下限 —— 仍达标，
   但不再跟主按钮抢视觉重心（主动作靠实心主题色取胜，不靠体积）。
   ⚠️ 一行放得下的前提是右栏够宽：视口 ≥1100px 时约 470px 可用，
      实测英文/阿语都能排下并留 18px 余量；更窄的视口（861~1050px）
      两栏布局下实在排不开，此时**整组**折到下一行 —— 见 H 组验收。 */
.pd-buy__alts { display: flex; gap: 6px; flex: 0 0 auto; }
.pd-buy__ask { padding-inline: 10px; font-size: .875rem; white-space: nowrap; }

/* WhatsApp：方形图标按钮。图标用 .ico-wa（mask + currentColor），
   所以这里只改 color 就能把图标染成官方绿。 */
.pd-buy__wa {
  width: var(--tap-min); padding: 0; flex: 0 0 auto;
  color: var(--wa); border-color: var(--line);
}
.pd-buy__wa .ico-wa { width: 20px; height: 20px; }
/* ⚠️ 顺序陷阱：.btn--outline:hover { color: var(--primary); border-color: var(--primary); }
   与本条特异性相同（都是 0,2,0），靠「后写者胜」。本文件在 03-components.css
   **之后** @import，所以这里能覆盖住 —— 别把这段挪到前面的文件里。 */
.pd-buy__wa:hover,
.pd-buy__wa:focus-visible {
  color: var(--wa); border-color: var(--wa); background: var(--wa-soft);
}

/* ---------- 实时阶梯提示 ----------
   无 JS 时为 hidden；有 JS 且配了阶梯价才显示。
   文案模板从 data-t-* 取，JS 只负责填值 —— 不在 JS 里写死语言。 */
.pd-buy__hint {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
  margin-block-start: 12px; padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  border-inline-start: 3px solid var(--primary);
  font-size: .8125rem; line-height: 1.5;
}
.pd-buy__hint[hidden] { display: none; }
.pd-buy__hint-ask { color: var(--ink-3); font-weight: 600; }
.pd-buy__hint-next { color: var(--ink-2); }
.pd-buy__hint-save {
  padding: 1px 7px; border-radius: 4px;
  background: var(--primary-soft); color: var(--primary);
  font-weight: 700; white-space: nowrap;
}
.pd-buy__hint-top { color: var(--ink-3); }

/* ---------- 起订量下限提示（2026-10-12 第 29 轮修 bug）----------
   数量低于 MOQ 时由 front.js 实时填充文案并取消 hidden。
   为什么不靠 `min` 属性的浏览器原生气泡：那气泡用的是**浏览器语言**
   （阿语客户可能看到英文），而且只在点提交那一刻才出现；
   这个提示是「边输边看到」，且文案随站点语言走。
   ⚠️ 必须显式写 `[hidden] { display: none; }` —— 一旦给元素设了
      `display: flex`，`hidden` 属性自身的 `display:none` 会被覆盖。 */
.pd-buy__warn {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-block-start: 8px;
  padding: 7px 11px;
  border-radius: var(--radius-sm);
  background: var(--err-bg);
  color: var(--err);
  border-inline-start: 3px solid var(--err);
  font-size: .8125rem;
  font-weight: 600;
  line-height: 1.45;
}
.pd-buy__warn[hidden] { display: none; }

/* 起订量 / 无 JS 降级说明 */
.pd-buy__moq {
  margin: 10px 0 0; color: var(--ink-3);
  font-size: .75rem; line-height: 1.55;
}

/* ---------- 样品勾选（第 97 轮）----------
   业主：「后台支持样品价格设置，样品是不限制起步采购数量的」＋
        「尽量别增加太多按钮」。所以这里**只有一个勾选框**（checkbox 本身
        就是最大的触控目标），勾上即切换买法，不加"买样品"按钮。
   整块是 <label> → 点标题/价格/说明任意位置都能勾，手机上不用瞄准那 18px。
   ⚠️ 不能用 `:has()` 做选中态：这里已经有 JS 在 `.pd-buy` 上打
      `pd-buy--sample`（它同时还要改数量上下限），两套状态源必然漂。
   ⚠️ 必须给 min-height: var(--tap-min)：整块可点，但视觉上要像一个 44px 的行。 */
.pd-sample {
  display: flex; align-items: flex-start; gap: 10px;
  margin-block-start: 12px; padding: 10px 12px;
  min-block-size: var(--tap-min);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-soft);
  cursor: pointer;
}
.pd-sample__cb {
  flex: 0 0 auto;
  inline-size: 18px; block-size: 18px;
  margin-block-start: 2px; margin-inline: 0;
  accent-color: var(--brand);
  cursor: pointer;
}
.pd-sample__body { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.pd-sample__title { color: var(--ink); font-size: .9375rem; font-weight: 600; }
.pd-sample__price { color: var(--brand); font-size: .875rem; font-weight: 600; }
.pd-sample__hint { color: var(--ink-3); font-size: .75rem; line-height: 1.5; }

/* 已勾选：整块换成主题色描边 + 浅主题底，和"未选"一眼可分 */
.pd-buy--sample .pd-sample {
  border-color: var(--brand);
  background: var(--primary-soft);
}

/* 样品模式下的价格提示：用主题色（这是"这次成交的价"，不是旁注） */
.pd-buy__hint-sample { color: var(--brand); font-weight: 600; }

/* ---------- 采购条款合并行（2026-10-12 第 29 轮）----------
   ⚠️ 业主明确要求保留：后台填的价格 = 出厂价（EXW），必须写清楚，
      否则客户会默认以为含运费 —— 这是纠纷高发点。
      但它原来独占价格表上方一大块（标题 + 三行长说明），
      现与表下的「美元计价 / 不含运费」小字合并成同一行。
      条款本身仍是**主题色加粗**（不能做成灰色小字 —— 灰色小字等于没写），
      完整条款释义挂在 tooltip 上，悬停可看，不占版面。 */
.pd-note__term {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--primary);
  font-weight: 700;
  white-space: nowrap;
  text-decoration: none;
  border-block-end: 1px dotted currentColor;
  cursor: pointer;
}
/* ★ 第61轮：贸易条款点击弹出的解释浮层（替代原生 title 悬停 —— 移动端无悬停，点不到）。
   点击 EXW/FOB 等标签弹出当前语种解释；点外部 / ESC 关闭。 */
.pd-term-pop {
  position: absolute;
  z-index: 60;
  max-width: 300px;
  padding: 9px 12px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--ink-2);
}
/* flex-basis 必须是 0（不是 auto）：auto 会让这一段的「理想宽度」等于整句长度，
   于是它整段掉到第二行、条款标签孤零零占一行。basis:0 才会与标签同排。 */
.pd-note__text { flex: 1 1 0; min-width: 0; }
.pd-note__lead { white-space: nowrap; }
.pd-note__lead-label { color: var(--ink-2); font-weight: 600; }
.pd-note__extra { flex: 1 1 100%; }

/* ---------- OEM / ODM 声明（第 68 轮：独立区块，版式同「规格参数」） ----------
   从左侧图库下方整块迁到这里，文字量没变，所以要按正文排版给足行高，
   不再用 13px 的小卡片样式。pre-line 让后台填的换行真的换行。 */
.pd-oem__text {
  margin: 0; color: var(--ink-2);
  font-size: 1rem; line-height: 1.8;
  white-space: pre-line;
  max-width: 76ch;                   /* 长段落别拉满整屏，一行太长反而难读 */
}

/* ==========================================================================
   如何报价（页尾独立区块）
   B2B 成交价 ≠ 页面标价。这里把「定制单独核价 / 条款按单谈 / 以 PI 为准」
   三步讲清楚。用编号步骤而非段落，扫一眼就懂。
   ========================================================================== */
.pd-quote__lead {
  margin: 0 0 20px; color: var(--ink-2);
  font-size: .9375rem; line-height: 1.7; white-space: pre-line;
}
.pd-quote__steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 14px;
}
.pd-quote__step {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 16px 18px; background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.pd-quote__num {
  flex: 0 0 auto; width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--primary-soft); color: var(--primary);
  font-size: .8125rem; font-weight: 700; line-height: 1;
}
.pd-quote__body { min-width: 0; }
.pd-quote__stitle {
  font-size: .9375rem; font-weight: 600; color: var(--ink);
  margin-block-end: 4px;
}
.pd-quote__stext {
  margin: 0; color: var(--ink-2);
  font-size: .875rem; line-height: 1.65;
}

/* ---------- 后台预览提示条 ---------- */
.preview-banner {
  background: var(--warn-bg); border-block-end: 1px solid var(--warn-border);
  color: var(--warn); font-size: 13px; padding: 8px 0;
}
.preview-banner .container { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.preview-banner b { font-weight: 700; }
.preview-banner a { color: var(--warn); text-decoration: underline; }
[dir="rtl"] .preview-banner .container { flex-direction: row-reverse; }

/* ---------- 窄屏适配 ----------
   ★ 第 68 轮：OEM 声明已不在左栏，.pd-aside / display:contents / order 那一套
     「把包裹层打散再排回去」的技巧全部作废，单栏就是自然的 图库 → 概要。 */
@media (max-width: 860px) {
  .pd-layout { grid-template-columns: 1fr; }
  .pd-gallery { order: 1; }
  .pd-summary { order: 2; }
  .spec-table th { width: 38%; }
}
@media (max-width: 520px) {
  .pd-tiers__title { padding: 10px 13px; }
  .tier-table td, .tier-table thead th { padding-inline: 13px; }
  .tier-price > .ltr-value { font-size: 16px; }
  .pd-buy { padding: 12px 13px; }
  /* 窄屏：数量器独占一行（标签回到横排、两端对齐），加购按钮整行 */
  .pd-buy__qty {
    flex: 1 1 100%; flex-direction: row; align-items: center;
    justify-content: space-between;
  }
  .pd-buy__btn { flex: 1 1 100%; }
  /* 次要动作整组占一行：「报价」撑满剩余宽度，WhatsApp 图标保持方形固定宽 */
  .pd-buy__alts { flex: 1 1 100%; }
  .pd-buy__ask { flex: 1 1 auto; }
  /* 触屏没有 hover：箭头在缩略图条两端，尺寸略收（30px，指尖仍可点），
     张数胶囊缩一号别压住图 */
  .pd-nav { width: 30px; height: 30px; opacity: .9; }
  .pd-strip { gap: 6px; }
  .pd-count { inset-block-end: 8px; inset-inline-end: 8px; font-size: 11px; }
  .pd-thumb { width: 58px; height: 58px; }
}
@media (min-width: 768px) {
  .pd-quote__steps { grid-template-columns: 1fr 1fr; }
}

/* 长图切段：容器已带边框/圆角，段图必须清零 —— 否则每段各画一圈边框，
   叠起来就是一道道接缝（第 84 轮）。要写在 .pd-desc img 之后且特异性更高。 */
.pd-desc .rt-stack { margin-block: 1.2em; }
.pd-desc .rt-stack img { margin: 0; border: 0; border-radius: 0; }
