/* ============================================================================
   购物车重写样式 · 阶段 4
   加载顺序：clientarea 的 bootstrap.min.css / icons.min.css / global.css
             → design-token.css → 本文件
   只被 cart/baiduvps 下的 tpl 引用，会员中心不加载 —— 所以这里可以放心覆盖
   bootstrap 的 .btn-primary 等公共类，不会波及 clientarea。
   （反过来说：**不要**把这里的规则挪进 clientarea/assets/css/，那套文件
   是购物车和会员中心共用的，改一处两边都变。）
   ============================================================================ */

/* ---------------------------------------------------------------- 画布
   .cartpage 只是个作用域钩子，不给它任何视觉属性 —— 它挂在 .row / #content /
   <form> 这类结构元素上，加背景或内边距会连带把布局搞歪。 */
.cartpage .card {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--sh-1);
}
.cartpage .card-title {
  color: var(--ink-1);
  font-weight: 650;
}
/* 商品名称卡和下面的配置卡之间留白。
   厂商给标题卡挂了 .mb-0（两张卡贴在一起当一个整体用），加上本文件给每张卡
   都描了边之后，两条边框直接叠在一起，看着像一张被横线劈开的卡。
   .mb-0 是 margin-bottom:0!important，只能用 !important 压回来。
   取值对齐的是**左右两栏之间那条 8px 的缝**（.col-xl-9 的 padding-right:8px），
   这样「产品名称↕配置清单」和「配置清单↔订单汇总」看起来是同一个间距。
   （原来取 16px 是照着右栏两张卡之间的 15px 定的 —— 那是纵向卡间距，
   和这里要对齐的横向栏间距不是一回事，实测偏大。） */
.cartpage .col-xl-9 > .card.mb-0 {
  margin-bottom: var(--s2) !important;
}

/* ---------------------------------------------------------------- 三步流程条 */
/* 放在 .row 内部当整宽列 —— 顶部避开头部浮层的 90px 净空继续由厂商的
   .zd-mt 提供。早先把它放在 .row 外面，结果整条被压在头部底下（top=0）。 */
.bv-steps {
  padding: 0 0 var(--s4);
}
.bv-steps ol {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.bv-steps li {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  color: var(--ink-4);
  white-space: nowrap;
}
/* 连接线：用 li 之间的伪元素，比额外套 div 少一层结构 */
.bv-steps li + li::before {
  content: "";
  width: 100%;
  min-width: 24px;
  height: 1px;
  background: var(--line-strong);
  margin: 0 var(--s3);
}
.bv-steps li + li { flex: 1 1 auto; }
.bv-steps .n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  font-size: 12px;
  font-weight: 600;
  flex: 0 0 auto;
}
.bv-steps .is-now { color: var(--ink-1); font-weight: 600; }
.bv-steps .is-now .n {
  background: var(--skin-accent);
  border-color: var(--skin-accent);
  color: var(--on-brand);
}
.bv-steps .is-done { color: var(--ink-2); }
.bv-steps .is-done .n {
  background: var(--brand-50);
  border-color: var(--brand-100);
  color: var(--skin-accent);
}
/* ≤1023px 时外层容器没有左右内边距，.row 的负外边距会把整条顶到视口边缘
   （窄屏上右边的「支付完成」直接被裁掉）。补回水平内边距。 */
@media (max-width: 1023px) {
  .bv-steps { padding-left: var(--s3); padding-right: var(--s3); }
}
/* 再窄一档，字号 / 圆点 / 连接线一起收一号 */
@media (max-width: 575px) {
  .bv-steps { padding: 0 var(--s3) var(--s3); }
  .bv-steps li { font-size: 12px; gap: var(--s1); }
  .bv-steps li + li::before { margin: 0 var(--s2); min-width: 8px; }
  .bv-steps .n { width: 19px; height: 19px; font-size: 11px; }
}

/* ---------------------------------------------------------------- 配置项行 */
.configoption_form .form-group.row {
  align-items: center;
  padding: var(--s3) 0;
  margin-bottom: 0;
  border-bottom: 1px solid var(--surface-sunk);
}
.configoption_form .form-group.row:last-of-type { border-bottom: 0; }
.configoption_form .col-form-label {
  color: var(--ink-3);
  font-size: 14px;
  padding-top: 0;
  padding-bottom: 0;
}
.configoption_form .bxs-help-circle { color: var(--ink-4) !important; }

/* ---------------------------------------------------------------- 规格按钮组
   厂商用 bootstrap 的 .btn-group + .btn-primary，选中态是 #0008ff 描边。
   这里改成品牌橙描边 + 淡橙底，并且解开 .btn-group 的「强制一行」——
   操作系统那类选项能有十几个，挤在一行会横向溢出到卡片外面。 */
.configoption_form .btn-group,
.configoption_form .btn-group-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
/* 这几条必须带 !important：规格按钮的标签是 .btn.btn-primary，会同时命中
   下面「主按钮统一换成品牌橙」那条（也带 !important）。两条都 important 时
   比的是特异度，这里 (0,3,0) 压过那边的 (0,2,0)，规格按钮才保持描边样式，
   不会被刷成一排实心橙块。 */
.configoption_form .btn-group > .btn,
.configoption_form .btn-group-toggle > .btn,
.configoption_form .btn-group-toggle > label.btn {
  flex: 0 0 auto;
  margin: 0;
  border-radius: var(--r-ctl) !important;
  border: 1px solid var(--line-strong) !important;
  background: var(--surface) !important;
  color: var(--ink-2) !important;
  font-size: 14px;
  font-weight: 400;
  padding: 7px 16px;
  box-shadow: none;
  transition: border-color var(--t-fast) var(--ease),
              background-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.configoption_form .btn-group > .btn:hover,
.configoption_form .btn-group-toggle > label.btn:hover {
  border-color: var(--brand-500) !important;
  color: var(--brand-600) !important;
  background: var(--surface) !important;
}
/* 选中态。两套选择器都要留：
   - .active 是 bootstrap 的 button 插件加的，但它绑在 **window load** 上，
     要等页面所有图片都下载完才执行。网慢的时候客户会看到一个「什么都没选中」
     的配置器（其实 input 早就 checked 了），实测就撞见过一次。
   - :has(> input:checked) 不依赖 JS，首屏就对。当浏览器不认识 :has 时整条规则
     被丢弃，所以必须和 .active 那条分开写，不能并进同一个选择器列表。 */
.configoption_form .btn-group > .btn.active,
.configoption_form .btn-group-toggle > label.btn.active {
  border-color: var(--skin-accent) !important;
  background: var(--brand-50) !important;
  color: var(--brand-700) !important;
  font-weight: 600;
}
.configoption_form .btn-group-toggle > label.btn:has(> input:checked) {
  border-color: var(--skin-accent) !important;
  background: var(--brand-50) !important;
  color: var(--brand-700) !important;
  font-weight: 600;
}
/* bootstrap 的 focus 蓝光环也要跟着换 */
.configoption_form .btn.focus,
.configoption_form .btn:focus {
  box-shadow: 0 0 0 3px var(--brand-100) !important;
  outline: 0;
}
/* 单选/复选原生控件在 label 里，视觉上不需要 */
.configoption_form .btn-group-toggle > label.btn > input[type="radio"],
.configoption_form .btn-group-toggle > label.btn > input[type="checkbox"] {
  position: absolute;
  clip: rect(0,0,0,0);
  pointer-events: none;
}

/* 周期按钮上的折扣角标 */
.configoption_form .cycle-select-discount {
  display: inline-block;
  margin-left: var(--s1);
  padding: 1px 5px;
  border-radius: var(--r-chip);
  background: var(--bad-500);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  vertical-align: 1px;
}

/* ---------------------------------------------------------------- 操作系统
   一行是「家族按钮组」，下一行是「具体版本下拉」。
   版本那个下拉留着不动：7 个选项都是「Windows 2008 R2 64位 企业版」这种长串，
   摊成按钮会占掉半屏，反而不如下拉。家族只有 5 个短词 + 有图标，才适合摊开。
   .bv-os-native 默认可见（脚本没跑起来时的退路），由脚本 display:none。 */
.bv-os-cell {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
}
.bv-os-family { flex: 0 0 100%; }
.bv-os-version { flex: 0 0 auto; min-width: 280px; }
.bv-os-btns { display: flex; flex-wrap: wrap; gap: var(--s2); }
.bv-os-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-2);
  border-radius: var(--r-ctl);
  font-size: 14px;
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease),
              background-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.bv-os-btn img { height: 18px; width: auto; flex: 0 0 auto; }
.bv-os-btn:hover { border-color: var(--brand-500); color: var(--brand-600); }
.bv-os-btn.is-on {
  border-color: var(--skin-accent);
  background: var(--brand-50);
  color: var(--brand-700);
  font-weight: 600;
}
.bv-os-btn:focus-visible { outline: 0; box-shadow: 0 0 0 3px var(--brand-100); }
@media (max-width: 768px) {
  .bv-os-btn { min-height: 44px; }
  .bv-os-version { flex: 0 0 100%; min-width: 0; }
}

/* ---------------------------------------------------------------- 下拉 / 输入 */
.configoption_form .form-control,
.configoption_form .bootstrap-select > .btn {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--ink-1);
  font-size: 14px;
  box-shadow: none;
}
.configoption_form .form-control:focus,
.configoption_form .bootstrap-select > .btn:focus {
  border-color: var(--skin-accent);
  box-shadow: 0 0 0 3px var(--brand-100);
}
.configoption_form .dropdown-menu .dropdown-item.active,
.configoption_form .dropdown-menu .dropdown-item:active,
.configoption_form .dropdown-menu li.selected > a {
  background: var(--brand-50) !important;
  color: var(--brand-700) !important;
}

/* 复选框选中色 */
.configoption_form .custom-control-input:checked ~ .custom-control-label::before {
  background: var(--skin-accent);
  border-color: var(--skin-accent);
}

/* ---------------------------------------------------------------- 数量滑块
   ⚠ 这里的滑块**不是** ion.rangeSlider —— 虽然那个库的 js/css 也被引进来了，
   实际渲染的是原生 <input type="range">，厂商在 configureproduct.tpl 的页内
   <style> 里给把手描了 #0080ff。所以按 .irs-* 改是没用的（踩过），得按
   原生伪元素改。特异度 (0,2,1) > 厂商的 (0,1,1)，不依赖加载顺序。 */
.configoption_form input[type='range'] {
  background: var(--surface-sunk);
  height: 4px;
  border-radius: 999px;
}
.configoption_form input[type='range']::-webkit-slider-thumb {
  border-color: var(--skin-accent);
}
.configoption_form input[type='range']::-moz-range-thumb {
  border-color: var(--skin-accent);
}
/* 数量步进器（− 数字 +）
   厂商原来拿汉字「一」当减号、「十」当加号（value="一" / value="十"），
   尺寸 31×35。已在模板里换成真正的 − / +（确认过 configureproduct.js 里
   只用 .btn_sub / .btn_add 当选择器，零处读 value，改文案不影响逻辑）。
   尺寸提到 36px，手机 44px —— 手机上原来 31px 宽，拇指经常点空。 */
.configoption_form .btn_sub,
.configoption_form .btn_add {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-2);
  border-radius: var(--r-ctl);
  font-size: 17px;
  line-height: 1;
  padding: 0;
  text-align: center;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.configoption_form .btn_sub:hover,
.configoption_form .btn_add:hover {
  border-color: var(--skin-accent);
  color: var(--skin-accent);
}
.configoption_form .btn_sub:active,
.configoption_form .btn_add:active { background: var(--brand-50); }
/* 中间那个数字框跟按钮对齐同高。
   ⚠ 必须带 !important：厂商这份 bootstrap.min.css 里写的是
   `.form-control{height:35px!important}`，不加就永远是 35px，
   按钮 44px、输入框 35px，三个控件的边框对不齐。 */
.configoption_form .configoption_range_val {
  height: 36px !important;
  text-align: center;
  font-family: var(--font-num);
  font-size: 14px;
}
@media (max-width: 768px) {
  .configoption_form .btn_sub,
  .configoption_form .btn_add { width: 44px; height: 44px; font-size: 19px; }
  .configoption_form .configoption_range_val { height: 44px !important; }
}

/* ion.rangeSlider 的皮肤留着 —— 别的商品的选项类型可能会用到它 */
.configoption_form .irs--flat .irs-bar,
.configoption_form .irs-bar { background: var(--skin-accent); }
.configoption_form .irs--flat .irs-handle > i:first-child,
.configoption_form .irs-slider { background: var(--skin-accent); }
.configoption_form .irs--flat .irs-from,
.configoption_form .irs--flat .irs-to,
.configoption_form .irs--flat .irs-single,
.configoption_form .irs-from,
.configoption_form .irs-to,
.configoption_form .irs-single { background: var(--skin-accent); }
.configoption_form .irs--flat .irs-from::before,
.configoption_form .irs--flat .irs-to::before,
.configoption_form .irs--flat .irs-single::before { border-top-color: var(--skin-accent); }

/* ---------------------------------------------------------------- 订单汇总卡
   粘顶：配置项一多，右侧总价就被滚出视野，客户改配置看不到价格变化。
   .col-xl-3 是 flex 子项、默认 stretch 满行高，所以粘的是里面的 .card。 */
/* ⚠ 粘的必须是**整根侧栏**，不能只粘里面第一张卡。
   sticky 元素会保留自己在文档流里的占位，往下平移时就直接压到后面的兄弟节点上——
   只粘「订单汇总」那张卡的话，一滚动它就盖住下面的「⚠ 警告」卡（实测盖 633px）。
   所以粘 .col-xl-3 本身：
   align-self:flex-start —— .row 是 flex，默认 stretch 会把列拉到整行高，sticky 就没有可移动的余量。

   刻意**没有**加 max-height + overflow-y 做内部滚动：那样侧栏会出现第二根滚动条，
   鼠标停在价格卡上滚页面会先滚这个内层框，页面像卡住。不限高也不会丢内容——
   侧栏比一屏高时，粘性额度用完后整列会跟着页面上移，警告卡自然就露出来了。

   跟随距离 = 行高 − 侧栏高（实测约 424px）。想让它跟得更久，得先把汇总卡压矮，
   而它现在 640~800px 高的主因是那 13 行 ¥0.00 —— 那条待办解决后这里会自动变好。 */
@media (min-width: 1200px) {
  .configoption_form .col-xl-3 {
    position: sticky;
    top: 90px;                 /* 站点头部 75px + 15px 呼吸 */
    align-self: flex-start;
    z-index: 5;
  }
}
.configoption_total .ordersummary {
  margin-bottom: var(--s3) !important;
  font-size: 13px;
}
.configoption_total .ordersummary td {
  padding: 6px 0 !important;
  vertical-align: top;
  color: var(--ink-2);
}
.configoption_total .ordersummary .color-999 { color: var(--ink-4) !important; }
.configoption_total .ordersummary hr { border-top-color: var(--line); }
/* 合计行 */
.configoption_total .ordersummary tr:last-child td {
  padding-top: var(--s2) !important;
  font-size: 15px;
}
.configoption_total .ordersummary tr:last-child td:last-child {
  color: var(--skin-accent) !important;
  font-size: 22px;
  font-weight: 700;
  font-family: var(--font-num);
}

/* 加购按钮：厂商用行内 style 绝对定位钉在卡片右下角，卡片一矮就压住表格。
   改成正常流 + 满宽，行内样式只能用 !important 压。 */
.configoption_total > .text-sm-right {
  position: static !important;
  margin-top: var(--s4) !important;
}
/* 主按钮统一换成品牌橙。注意只换配色，**不要**在这里写 width:100% ——
   结算页有 5 个 .btn-primary（删除 / 继续购物 / 去结算…），全拉满宽会排版崩。
   满宽只给「加入购物车」那一个。 */
.cartpage .btn-primary {
  background: var(--skin-accent) !important;
  border-color: var(--skin-accent) !important;
  color: var(--on-brand) !important;
  border-radius: var(--r-ctl);
  font-weight: 600;
  box-shadow: none;
  transition: background-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.cartpage .btn-primary:not(.btn-sm) { padding: 9px 20px; font-size: 14px; }
.cartpage .btn-primary:hover {
  background: var(--skin-accent-deep) !important;
  border-color: var(--skin-accent-deep) !important;
}
.configoption_total #addToCartBtn,
.configoption_total #addToCartBtnTwo {
  width: 100%;
  justify-content: center;
  font-size: 15px;
  padding: 11px 20px !important;
  box-shadow: var(--sh-brand);
}
.configoption_total #addToCartBtn:hover,
.configoption_total #addToCartBtnTwo:hover { transform: translateY(-1px); }
/* 移动端底部总价条 */
.mobile-bottom-total {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  height: auto !important;
  line-height: 1.4 !important;
  padding: var(--s3) var(--s4) !important;
  border-top: 1px solid var(--line);
}
.mobile-bottom-total .total {
  color: var(--skin-accent) !important;
  font-weight: 700 !important;
  font-size: 17px !important;
  font-family: var(--font-num);
}
.mobile-bottom-total .btn-primary { width: auto; flex: 0 0 auto; }

/* 警告卡 */
.cartpage .jgao {
  background: var(--warn-50);
  border-color: #F3E0BC;
}
.cartpage .jgao .card-title { color: #8A5A08; }
.cartpage .jgao p { color: #6B4A10; font-size: 13px; line-height: 1.7; margin: 0; }

/* ---------------------------------------------------------------- 配置详情展开器
   厂商这个「按钮」其实是一个 <font> 标签里塞了个 &gt; 字符，还指定了
   font-family:cursive —— 浏览器会挑 Comic Sans / Apple Chancery 之类的手写体，
   所以看着特别土。展开态靠给它加 .zk 然后 rotate(90deg)。

   ⚠ 标签必须留着 <font>，class 必须留着 .zk：viewcart.tpl 的 JS 是
   `$(this).find('font').toggleClass('zk')` + `.siblings('.info').slideToggle()`，
   改标签名或类名就点不动了。所以这里只重画外观，不动结构：
   把那个 > 字符用 font-size:0 藏掉，改用 ::before 拿两条边框画正经的 chevron，
   父元素的 rotate(90deg) 继续负责「右→下」的翻转，加上过渡就不再是硬切。 */
/* ⚠ .title 保持厂商的 display:block（来自 .goods_info span{display:block}）。
   我一开始把它改成 inline-flex，结果后面那些 .info 是 float:left 的，
   title 不再独占一行，配置详情就浮到主机名同一行去了 —— 别动它的 display。
   同理 <font> 的 float:left 也留着：文字绕排就是靠它。 */
.cartpage .goods_info .title {
  color: var(--ink-1);
  font-size: 13px;
  transition: color var(--t-fast) var(--ease);
}
.cartpage .goods_info .title:hover { color: var(--brand-700); }
.cartpage .goods_info .title font {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin: 0 4px 0 0;
  font-size: 0;               /* 藏掉那个 &gt; 字符本身 */
  font-family: inherit;       /* 干掉 cursive */
  color: transparent;
  flex: 0 0 auto;
  transition: transform var(--t-base) var(--ease);
}
.cartpage .goods_info .title font::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-left: -2px;
  border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(-45deg);  /* 折叠态：指向右 */
}
.cartpage .goods_info .title:hover font::before {
  border-color: var(--brand-600);
}
/* 展开态：厂商加 .zk 转 90°，把 chevron 从「右」翻到「下」。
   原规则还带了个 margin-top:-4px 的手动微调，布局改了之后要撤掉。 */
.cartpage .goods_info .title .zk {
  transform: rotate(90deg);
  margin-top: 0;
}
/* .info 只改颜色。厂商给的是 width:25% + float:left + text-indent:27px，
   动它的盒模型很容易把四列布局挤崩，不值当。 */
.cartpage .goods_info .info { color: var(--ink-3); }

/* ---------------------------------------------------------------- 购物车 / 结算页 */
.cartpage .alert-danger {
  background: var(--bad-50);
  border-color: #F5C6CB;
  color: #A12A1E;
  border-radius: var(--r-ctl);
}
.cartpage .table thead th {
  border-bottom: 1px solid var(--line);
  color: var(--ink-3);
  font-weight: 600;
  font-size: 13px;
}
.cartpage .table td { border-top-color: var(--surface-sunk); color: var(--ink-2); }
.cartpage a { color: var(--skin-accent); }
.cartpage a:hover { color: var(--skin-accent-deep); }

/* ---------------------------------------------------------------- 商品列表页
   /cart 用的是 web 主题的 cartindex.css（已随全站换肤走 --skin-accent），
   这里只补卡片本身的层次：厂商版本是纯白无边框，卡片之间靠留白区分，
   信息一多就糊成一片。
   卡片容器是 .card-item-wrap.por-card —— 从「前往选购」按钮往上回溯一层拿到的，
   别照着 .goods-item / .item 这类名字猜，这套模板里没有（我先猜错过一轮）。 */
.cartpage .card-item-wrap.por-card {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: box-shadow var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease);
}
.cartpage .card-item-wrap.por-card:hover {
  border-color: var(--brand-100);
  box-shadow: var(--sh-3);
  transform: translateY(-3px);
}
/* 「前往选购」：可点区**本来就是**整个 255×34 的框（外面的 <a> 是 inline、
   getBoundingClientRect 只报 16px 的行盒，但里面那个 inline-block 的
   .por-label 是它的子节点，所以整框都命中 —— 五点命中测试全部通过）。
   这里要修的不是「点不到」，是 34px 在手机上够不到 44px 的触控标准。 */
.cartpage .card-item-wrap .por-label {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  border-radius: var(--r-ctl);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
@media (max-width: 768px) {
  .cartpage .card-item-wrap .por-label { min-height: 44px; }
}
/* 卡片里那段红色粗体的购买须知（周期/仅Linux/不支持退款/限购…）。
   内容是**必须让客户看到的成交条件**，一个字都不能藏，问题只在表现：
   14px 红色 700 粗体 5 行，占掉卡片 22~28% 的高度，比产品名还抢眼，
   八张卡排在一起满屏警告色。这里降成 12px 常规字重的灰色脚注，
   左边一条竖线表示「这是附注」—— 信息量不变，视觉权重让给规格和价格。
   源头在后台商品描述的 <b style="color: red">，是行内样式，
   所以颜色这条必须 !important（样式表的 important 才压得过行内的普通声明）。 */
.cartpage .card-desc p > b {
  display: block;
  margin-top: var(--s2);
  padding-left: 8px;
  /* 这四个值由后台「主题外观」→「列表页购买须知」的下拉决定：
     低调脚注 = 12px/400/灰/2px 竖线；厂商原样 = 14px/700/红/无竖线。
     一个下拉在插件里展开成四个变量，比在这儿写两套规则再切换 class 干净。 */
  border-left: var(--bh-tips-bar, 2px) solid var(--line-strong);
  color: var(--bh-tips-color, var(--ink-3)) !important;
  font-size: var(--bh-tips-fs, 12px);
  font-weight: var(--bh-tips-fw, 400);
  line-height: 1.6;
}
/* 「带宽」那一行也被后台写成了红色（同样是行内 style），和上下几行规格不一致，
   而且红色在这儿是警告语义。改成和其他规格同色、靠加粗保留强调。 */
.cartpage .card-desc li span[style] {
  color: var(--ink-1) !important;
  font-weight: 600;
}

/* hover 时实心反白，让「这是个按钮」更明确 */
.cartpage .card-item-wrap.por-card:hover .por-label {
  background: var(--skin-accent);
  border-color: var(--skin-accent);
  color: var(--on-brand);
}

/* ---------------------------------------------------------------- 结算底栏（优惠码 / 总计）
   1) 「应用」两个字被顶到框底下去了。厂商给按钮的是 padding:9px 20px + line-height:35px，
      而它在 .input-group 里的高度是被 align-items:stretch 拉成 .custom-file 的 35px，
      于是 35px 的行盒从 9px 的 padding-top 处起画 —— 文字中线落在 26.5px，
      比框中线 17.5px 低了 9px，底部还被裁掉一截。改成 flex 居中 + line-height:1
      才是真的在中间；高度仍由 stretch 决定，不会变。
   2) 总价 22px，而「所购产品」里每件的小计是行内 style 写死的 18px —— 对不上。
      根因：.font-size-18 这个工具类在 bootstrap.min.css:11912 被写成了 font-size:22px。
      它是全局类，只能在 .cartpage 作用域内往回压。 */
.cartpage #promo .input-group-append .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-top: 0;
  padding-bottom: 0;
  line-height: 1;
}
/* 顺带：输入框里的字实测只有 8.125px（厂商写 .8125rem，而 html 是
   font-size:62.5% 即 1rem=10px，于是缩水成 8px），placeholder 基本看不清 */
.cartpage #promo .form-control { font-size: 13px; }

/* 总计的金额跟商品小计统一到 18px（含 mobile 那份，两处容器都是 .font-size-16）。
   「所购产品」里的 strong 带行内 font-size:18px，行内优先级更高，不受这条影响。 */
.cartpage .font-size-16 strong.font-size-18 { font-size: 18px; }

/* ---------------------------------------------------------------- 空购物车
   厂商原版是 <p style="text-align:center;line-height:300px">购物车数据为空！</p>
   —— 一个 540px 高的大白板，没图标没按钮，客户走到这儿就断了。 */
.bv-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--s8) var(--s4);
  text-align: center;
}
.bv-empty-ico { color: var(--ink-4); opacity: .55; margin-bottom: var(--s4); }
.bv-empty-t {
  margin: 0 0 var(--s2);
  color: var(--ink-1);
  font-size: 16px;
  font-weight: 600;
}
.bv-empty-d { margin: 0 0 var(--s5); color: var(--ink-3); font-size: 13px; }
.bv-empty-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 var(--s6);
  border-radius: var(--r-ctl);
  background: var(--skin-accent);
  color: var(--on-brand) !important;   /* .cartpage a 会把它染成主色文字 */
  font-size: 14px;
  text-decoration: none;
  transition: background-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.bv-empty-btn:hover {
  background: var(--skin-accent-deep);
  color: var(--on-brand) !important;
  box-shadow: var(--sh-2);
}
@media (max-width: 768px) {
  .bv-empty { padding: var(--s6) var(--s4); }
  .bv-empty-btn { min-height: 44px; width: 100%; max-width: 280px; }
}

/* ---------------------------------------------------------------- 未登录提示
   原来是红底框里一句「您还未登录！请先 登陆>」（「登陆」是错字），
   而且购物车里最关键的转化点只是个小文字链。 */
.cartpage .bv-alert-line {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s3);
  font-weight: 500;
}
.cartpage .bv-alert-btn {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 var(--s4);
  border-radius: var(--r-ctl);
  background: var(--skin-accent);
  color: var(--on-brand) !important;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--t-fast) var(--ease);
}
.cartpage .bv-alert-btn:hover { background: var(--skin-accent-deep); color: var(--on-brand) !important; }
/* 手机上 30px 太矮，够不上触控标准（和「前往选购」用的是同一条尺）。
   这里给 40px —— 44px 会把那条红底提示撑得比正文卡片还抢眼。 */
@media (max-width: 768px) {
  .cartpage .bv-alert-btn { min-height: 40px; padding: 0 var(--s5); }
}

/* ---------------------------------------------------------------- 订单汇总的「已含」
   ¥0.00 那些行由 configureproduct.tpl 末尾的脚本改写成「已含」并打上
   data-bv-zero，这里只负责让它别抢眼。 */
.cartpage .ordersummary td[data-bv-zero] {
  color: var(--ink-4);
  font-weight: 400;
}

/* ---------------------------------------------------------------- 支付完成页
   这个页面走 web 主题的 chrome（global/header/index.css + design-token），
   clientarea 的 bootstrap 没加载，所以容器、间距、头部避让都得自己给。 */
.bv-done {
  max-width: 1200px;
  margin: 0 auto;
  padding: 120px var(--s4) var(--s9);   /* 头部是绝对定位的，得自己让出来 */
}
.bv-done-card {
  margin-top: var(--s6);
  padding: var(--s9) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--sh-1);
  text-align: center;
}
/* 对勾颜色可在后台「主题外观」→「支付完成页」里改，兜底用设计系统的成功绿 */
.bv-done-ico { color: var(--bh-done-ico, var(--ok-500)); margin-bottom: var(--s4); line-height: 0; }
.bv-done-t {
  margin: 0 0 var(--s3);
  color: var(--ink-1);
  font-size: 24px;
  font-weight: 600;
}
.bv-done-d {
  margin: 0 auto var(--s6);
  max-width: 520px;
  color: var(--ink-2);
  font-size: 14px;
  line-height: 1.7;
}
.bv-done-btns {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  justify-content: center;
  margin-bottom: var(--s6);
}
/* 这里必须带 .cartpage 前缀：上面那条 .cartpage a{color:var(--skin-accent)} 是
   (0,2,0)，光写 .bv-done-btn 只有 (0,1,0)，次要按钮的字会被染成橙色。 */
.cartpage .bv-done-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  padding: 0 var(--s6);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--ink-2);
  font-size: 14px;
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
              background-color var(--t-fast) var(--ease);
}
.cartpage .bv-done-btn:hover { border-color: var(--skin-accent); color: var(--skin-accent); }
.cartpage .bv-done-btn.is-main {
  border-color: var(--skin-accent);
  background: var(--skin-accent);
  color: var(--on-brand);
}
.cartpage .bv-done-btn.is-main:hover {
  background: var(--skin-accent-deep);
  border-color: var(--skin-accent-deep);
  color: var(--on-brand);
}
.bv-done-help { margin: 0; color: var(--ink-3); font-size: 13px; }
.bv-done-help a { color: var(--skin-accent); text-decoration: none; }
.bv-done-help a:hover { text-decoration: underline; }
@media (max-width: 768px) {
  .bv-done { padding: 90px var(--s3) var(--s7); }
  .bv-done-card { padding: var(--s7) var(--s4); }
  .bv-done-t { font-size: 20px; }
  .cartpage .bv-done-btn { width: 100%; min-height: 46px; }
}

/* ---------------------------------------------------------------- 无障碍 */
@media (prefers-reduced-motion: reduce) {
  .cartpage *,
  .configoption_form * { transition: none !important; }
  .cartpage .btn-primary:hover,
  .cartpage .por-goods-item:hover { transform: none; }
}


/* ---------------------------------------------------------------- 页内工具条
   商品列表页（product.tpl）标题下面的「排序 / 筛选 / 搜索」。
   这个页面没有分页，一个分组最多能渲染 63 个卡片（全站 379 个 / 47 组），
   所以就地过滤比翻页更实用。默认 hidden，JS 就绪才显示 —— 脚本挂了不影响下单。 */
.cartpage .bv-tools {
  margin: -4px 0 20px;
  padding: 12px 16px;
  background: var(--surface-2, #F5F7FA);
  border: 1px solid var(--line, #E7EBF0);
  border-radius: var(--r-card, 8px);
}
.cartpage .bv-tools[hidden] { display: none; }

.cartpage .bv-tools-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
}

/* ---- 搜索 ---- */
.cartpage .bv-tools-search {
  position: relative;
  flex: 1 1 260px;
  min-width: 200px;
}
.cartpage .bv-tools-input {
  width: 100%;
  height: 36px;
  padding: 0 34px 0 12px;
  border: 1px solid var(--line-strong, #CFD7E3);
  border-radius: var(--r-ctl, 6px);
  background: #fff;
  /* 这套页面 html{font-size:62.5%}（1rem=10px），厂商到处用 .8125rem 其实只有 8px。
     这里一律写 px，别用 rem。 */
  font-size: 13px;
  color: var(--ink-1, #1D2129);
  outline: 0;
}
.cartpage .bv-tools-input:focus {
  border-color: var(--skin-accent, #D9520A);
  box-shadow: 0 0 0 3px var(--brand-100, #F7D9C9);
}
/* 搜索图标：纯 CSS 画，不引图标字体（这页没加载 iconfont） */
.cartpage .bv-tools-ico {
  position: absolute;
  right: 12px;
  top: 50%;
  width: 12px;
  height: 12px;
  margin-top: -7px;
  border: 1.5px solid var(--ink-4, #A6AEBB);
  border-radius: 50%;
  pointer-events: none;   /* 别挡住输入框的点击 */
}
.cartpage .bv-tools-ico::after {
  content: "";
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 5px;
  height: 1.5px;
  background: var(--ink-4, #A6AEBB);
  transform: rotate(45deg);
}

/* ---- 排序按钮组 ---- */
.cartpage .bv-tools-sort {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}
.cartpage .bv-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--line-strong, #CFD7E3);
  border-radius: var(--r-ctl, 6px);
  background: #fff;
  font-size: 13px;
  line-height: 1;
  color: var(--ink-2, #4E5969);
  cursor: pointer;
  transition: border-color var(--t-fast, .15s) var(--ease, ease),
              color var(--t-fast, .15s) var(--ease, ease),
              background-color var(--t-fast, .15s) var(--ease, ease);
}
.cartpage .bv-sort:hover {
  border-color: var(--skin-accent, #D9520A);
  color: var(--skin-accent, #D9520A);
}
.cartpage .bv-sort.is-on {
  border-color: var(--skin-accent, #D9520A);
  background: var(--brand-50, #FCF1EB);
  color: var(--skin-accent, #D9520A);
  font-weight: 600;
}
/* 升降序箭头：未选中的排序键不显示方向，选中后按 data-dir 翻转 */
.cartpage .bv-sort .bv-arrow {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  opacity: 0;
  transition: opacity var(--t-fast, .15s) var(--ease, ease);
}
.cartpage .bv-sort[data-dir="asc"] .bv-arrow {
  opacity: 1;
  border-bottom: 5px solid currentColor;
}
.cartpage .bv-sort[data-dir="desc"] .bv-arrow {
  opacity: 1;
  border-top: 5px solid currentColor;
}

/* ---- 只看有货 ---- */
.cartpage .bv-tools-chk {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 13px;
  color: var(--ink-2, #4E5969);
  cursor: pointer;
  user-select: none;
}
.cartpage .bv-tools-chk input {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--skin-accent, #D9520A);
  cursor: pointer;
}

/* ---- 计数 / 提示 / 重置 ---- */
.cartpage .bv-tools-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin-top: 8px;
  font-size: 12px;
  line-height: 18px;
  color: var(--ink-3, #86909C);
}
.cartpage .bv-tools-hint::before { content: "· "; }
.cartpage .bv-tools-hint[hidden] { display: none; }
.cartpage .bv-tools-reset {
  padding: 0;
  border: 0;
  background: none;
  font-size: 12px;
  color: var(--skin-accent, #D9520A);
  cursor: pointer;
  text-decoration: underline;
}
.cartpage .bv-tools-reset[hidden] { display: none; }

/* 筛完一个不剩时给个交代，否则底下是一片空白 */
.cartpage .bv-tools.is-empty .bv-tools-meta::after {
  content: "没有匹配的商品，换个词或点重置试试";
  color: var(--ink-2, #4E5969);
}

@media (max-width: 768px) {
  .cartpage .bv-tools { padding: 10px 12px; }
  .cartpage .bv-tools-search { flex: 1 1 100%; }
  .cartpage .bv-tools-sort { flex: 1 1 auto; }
  .cartpage .bv-sort { flex: 1 1 0; justify-content: center; padding: 0 8px; }
}


/* ------------------------------------------------- 商品介绍里的配置图标
   后台商品描述里写的是 <img width="30px" height="30px"> + 13px 的说明文字，
   而 img 默认 vertical-align:baseline —— baseline 对齐是把图片的**底边**
   放在文字基线上，30px 的图整个顶上去，实测图标中线比文字中线高 10px，
   还把行盒从 22px 撑到 37px，所以每行看着都是「图标在上、字在下」。

   尺寸和对齐都在这里用 CSS 收口，不去改后台那 42 条商品描述：
   - width/height 是 HTML 属性（表现性提示），任何作者样式都能压过它，不用 !important；
   - margin-right 写在行内 style 里，要压就得 !important。
   改后台的话得逐条改 254 处 img，而且下次录入新商品又会回到 30px。 */
.cartpage .card-desc li img,
.cartpage .card-desc p img {
  width: 20px;
  height: 20px;
  vertical-align: middle;
  margin-right: 6px !important;
}
/* 行高跟着收回来，图标不再撑高行盒后，各行间距才均匀 */
.cartpage .card-desc li {
  line-height: 22px;
}
