* {
   box-sizing: border-box
}

body {
   margin: 0;
   background: #f4f5f7;
   color: #262626;
   font: 14px/1.6 Inter, "Microsoft YaHei", sans-serif
}

a {
   text-decoration: none;
   color: inherit
}

.wb-top {
   height: 68px;
   background: #fff;
   border-bottom: 1px solid #e8e8e8;
   display: flex;
   align-items: center;
   padding: 0 28px;
   gap: 35px;
   position: sticky;
   top: 0;
   z-index: 10
}

.wb-logo img {
   width: 155px;
   display: block
}

.wb-top nav {
   display: flex;
   gap: 25px
}

.wb-top>div {
   margin-left: auto;
   display: flex;
   gap: 18px;
   font-weight: 700
}

.wb-shell {
   display: grid;
   grid-template-columns: 220px 1fr;
   min-height: calc(100vh - 68px)
}

/* 工作台布局：左侧导航固定、不跟随整页滚动，与右侧内容分开控制。
   会员中心（.wb-shell.member-shell）、采购工作台、厂家经营台共用同一套 .wb-shell，
   侧边栏行为必须一致 —— 所以这里不再用 [data-page] 限定（原来只有厂家经营台带这个属性，
   会员中心和采购工作台的侧边栏是 static，会跟着整页滚走）。
   注意工作台页面的 <header class="wb-top"> 会由服务端替换成商城壳
   （.gr-topbar 34px + .gr-market-header，两者都 static），所以顶栏会随页面滚走，
   侧边栏直接贴视口顶（top:0）并占满整屏高；aside 自己可滚动（overflow-y:auto +
   overscroll-behavior:contain），菜单再长也只滚它自己，不拉长页面也不影响右侧。
   右侧内容不足一屏时容器高度等于 aside 高度，sticky 没有可粘空间，
   此时侧边栏本来就在视口内、看不出差别；内容够长时才体现固定效果。 */
.wb-shell>aside {
   position: sticky;
   top: 0;
   height: 100vh;
   overflow-y: auto;
   overscroll-behavior: contain
}

.wb-shell>main {
   min-height: calc(100vh - 68px)
}

aside {
   background: #20232a;
   color: #cbd0d7;
   padding: 22px 14px
}

aside .wb-role {
   padding: 12px 12px 22px;
   color: #888;
   font-size: 11px;
   letter-spacing: .1em
}

.wb-role strong {
   display: block;
   color: #fff;
   font-size: 18px;
   letter-spacing: 0;
   margin-top: 5px
}

aside>a {
   display: block;
   padding: 10px 14px;
   border-radius: 6px;
   margin: 2px 0
}

/* ⚠️ 选择器**必须限定作用域**（.wb-side）：原来写的是无作用域的 `aside>a:hover / aside>a.on`，
   会命中**任何** aside 里的选中链接 —— 消息通知页的分类栏正是
   `<aside class="mb-msg-cats"><a class="on">`，被这里的 `color:#fff!important` 压过
   `.mb-msg-cats a.on{color:#c51b21}`，变成「浅红底(#fdecec) + 白字」几乎看不见
   （2026-09-24 用户报「分类选中字体背景变白了看不清」；买家侧 /member/messages 同样中招）。
   工作台侧栏的 <a class="wb-item"> 就是 .wb-side 的直接子元素，收窄成 .wb-side>a 后侧栏行为不变
   —— 选中/悬停的底色仍由 workbench-shell.css 的 .wb-side .wb-item(.on/:hover) 决定，这里只兜底文字色。 */
.wb-side>a:hover,
.wb-side>a.on {
   background: #e7272d;
   color: #fff !important
}

aside hr {
   border: 0;
   border-top: 1px solid #3a3d44;
   margin: 18px 9px
}

main {
   padding: 28px;
   min-width: 0
}

.wb-welcome {
   background: linear-gradient(120deg, #a80f16, #ed383d);
   color: #fff;
   border-radius: 13px;
   padding: 27px 30px;
   display: flex;
   align-items: center;
   justify-content: space-between
}

/* ⚠️ 类名 2026-09-23 由 `supplier` 改为 **`wb-supplier`**：`supplier` 太通用，被两份公共样式命中 ——
   commerce.css 的卡片列表（`.supplier{background:var(--gr-card)!important;border;box-shadow}`）
   与 marketplace-compact.css 的 `.supplier{padding:14px!important}`，
   它们把这块深蓝渐变欢迎区刷成**白底**（并改掉内边距），而 `.wb-welcome` 的字色是白色 →
   小字标（带字间距的那行）与标题几乎看不见、白底上的白色文字按钮也没了轮廓。
   改名后不再与公开页的厂家卡片（/manufacturers 等）共用类名。 */
.wb-welcome.wb-supplier {
   background: linear-gradient(120deg, #142941, #225b78)
}

.wb-welcome small {
   letter-spacing: .12em;
   opacity: .75
}

.wb-welcome h1 {
   font-size: 30px;
   margin: 3px 0
}

/* ⚠️ commerce.css 有条全局 `h1~h6 { color: var(--gr-title) }`（#1f2329 深色），而欢迎区是深色渐变底
   （买家红 / 商家蓝）—— 不显式提亮的话标题就跟底色糊在一起。
   commerce.css 自己已经给 .geo-strip / .graph / .portal-dark 做过同样的事，`.wb-welcome` 当年漏了。 */
.wb-welcome h1,
.wb-welcome h2,
.wb-welcome h3 {
   color: #fff
}

.wb-welcome p {
   margin: 0;
   opacity: .84
}

.wb-primary {
   border: 0;
   background: #fff;
   color: #1f2329;
   padding: 12px 20px;
   border-radius: 7px;
   font-weight: 900;
   /* `<a class="wb-primary">` 与 `<button class="wb-primary">` 外观必须一致：
      button 会被 commerce.css 的 `body button` 规则撑成 flex 居中并给 min-height，
      锚点则落成块级文本（没有按钮感、高度也不同）。这里显式对齐两者。 */
   display: inline-flex;
   align-items: center;
   justify-content: center;
   min-height: 42px;
   line-height: 1.2;
   text-decoration: none;
   white-space: nowrap
}

.wb-primary:hover {
   color: #c51b21
}

.wb-supplier .wb-primary {
   color: #164868
}

.wb-stats {
   display: grid;
   grid-template-columns: repeat(4, 1fr);
   gap: 13px;
   margin: 18px 0
}

.wb-stats article {
   background: #fff;
   border: 1px solid #e7e7e7;
   border-radius: 9px;
   padding: 18px
}

.wb-stats span,
.wb-stats b {
   display: block
}

.wb-stats span {
   color: #777
}

.wb-stats b {
   font-size: 27px;
   margin-top: 5px
}

.wb-auth {
   background: #fff7e8;
   border: 1px solid #f2d79d;
   border-radius: 8px;
   padding: 12px 16px;
   margin-bottom: 18px;
   color: #765316
}

/* 隐藏态必须显式写：将来若给 .wb-auth 加 display，作者样式会顶掉 UA 的 `[hidden]{display:none}`
   （同类处理见 .wb-nav-badge[hidden]）。采购工作台登录成功后不再展示这条提示（2026-09-29 用户要求），
   元素默认 hidden、只在未登录 / 读取失败时由 buyer-workbench.js 的 state() 显出来。 */
.wb-auth[hidden] {
   display: none
}

/* ⚠️ 工作台所有页不再展示「XX 数据已同步 / 请返回 XX」这类**绿底状态提示**（2026-09-29 用户要求，
   例：member-invoices.js 的「发票数据已同步。电子发票开出后可在这里下载。返回采购工作台」）。
   .ready 就是「成功态」的唯一标记 ⇒ 一处 CSS 覆盖全部工作台页，**不要**去 20 多个
   xx-workbench / member-* / supplier-* 脚本里把 state(..., true) 一行行删掉（那样必然漏改、且新页面
   又会加回来）。
   未登录 / 读取失败的**黄底引导必须保留**（很多页只有它给出登录入口），所以只隐藏 .ready 态。
   注：采购工作台 `/member/buyer` 在 2026-09-29 早些时候（A25）已单独改成「成功路径不再渲染」，
   与本规则是同一个目的（保留即可，不要因为「机制不统一」把它回退）。
   ⚠️ 曾经唯一的例外是会员中心首页（/member）那条「当前账号：UID … · 退出并切换账号」的账号条
   （带 .keep 的绿条）—— 2026-09-29 晚用户要求「这个绿条取消掉」，member-center.js 不再渲染它，
   随它一起生效的 `.keep` 豁免也一并删掉 ⇒ **全站不再有任何绿底成功条**。
   首页要登出请走「资料与账号安全」页（/member/profile 的 .mb-logout 按钮，带二次确认）；
   账号信息在会员首页「资料与账号安全」卡的 #profileAccount 里，不要再往 #authState 写成功态。 */
.wb-auth.ready {
   background: #effaf4;
   border-color: #bfe6cf;
   color: #22613b;
   display: none
}

/* 空横条不占位：renderWorkbench 把各页 `#authState` 的「正在读取…」初始文案统一清空
   （2026-09-29 用户要求：加载提示改成列表内的骨架动画，不要横条），加载期它就是空的。
   页面脚本写入未登录 / 读取失败的黄底提示后元素变非空、自动显示出来。 */
.wb-auth:empty {
   display: none
}

/* 工作台列表的加载骨架：由 workbench-loading.js 填进 `#xxxRows` 容器，真实数据渲染时整段覆盖。
   2026-09-29 优化（用户要求「加载动画优化一下」）：按容器形态给不同骨架 —— 卡片列表出卡片形状、
   表格出整行、其余出文本行；微光也调柔和（300% / 1.8s，原来是 400% / 1.4s，闪得偏急）。
   ⚠️ width:100% 不能省：占位容器（.wb-empty / .od-cards）多为 flex 居中，不写宽度骨架会被压成一条。 */
.wb-skeleton {
   display: grid;
   gap: 10px;
   width: 100%;
   padding: 14px 4px
}

/* 所有骨架块的公共底纹。文本行与卡片缩略图分开写选择器：卡片缩略图用 <b>，
   免得被下面 i 的行高/宽度规则接管。 */
.wb-skeleton i,
.wb-skeleton-card>b {
   display: block;
   border-radius: 7px;
   background: linear-gradient(90deg, #eff2f6 25%, #e4e9f0 37%, #eff2f6 63%);
   background-size: 300% 100%;
   animation: wb-skeleton 1.8s ease-in-out infinite
}

.wb-skeleton i {
   height: 14px
}

.wb-skeleton i:nth-child(2) {
   width: 88%
}

.wb-skeleton i:nth-child(3) {
   width: 62%
}

/* 表格（.mb-table / .wb-table）：整宽 + 更高的行、行距贴近真实行高，像数据在逐行填进来 */
.wb-skeleton-rows {
   gap: 15px
}

.wb-skeleton-rows i {
   width: 100%;
   height: 18px;
   border-radius: 6px
}

.wb-skeleton-rows i:nth-child(2) {
   width: 92%
}

.wb-skeleton-rows i:nth-child(4) {
   width: 74%
}

/* 卡片列表（.od-cards / .merchant-offers / .merchant-reviews / .mb-fav-grid）：
   两张「缩略图 + 标题 + 副标题」的卡片骨架，形状与真实订单 / 商品卡一致 */
.wb-skeleton-cards {
   grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
   gap: 12px
}

.wb-skeleton-card {
   display: flex;
   gap: 12px;
   align-items: center;
   padding: 14px;
   border: 1px solid #eef1f5;
   border-radius: 10px
}

.wb-skeleton-card>b {
   width: 56px;
   height: 56px;
   border-radius: 8px;
   flex: 0 0 auto
}

.wb-skeleton-card>span {
   display: grid;
   gap: 8px;
   flex: 1
}

.wb-skeleton-card>span i {
   height: 12px;
   border-radius: 6px
}

.wb-skeleton-card>span i:nth-child(1) {
   width: 64%
}

.wb-skeleton-card>span i:nth-child(2) {
   width: 40%
}

@keyframes wb-skeleton {
   from {
      background-position: 100% 50%
   }

   to {
      background-position: 0 50%
   }
}

.wb-auth a {
   font-weight: 800;
   text-decoration: underline
}

.wb-panel {
   background: #fff;
   border: 1px solid #e5e5e5;
   border-radius: 10px;
   padding: 20px;
   margin-bottom: 16px
}

.wb-panel-head {
   display: flex;
   justify-content: space-between;
   align-items: end
}

.wb-panel h2 {
   margin: 0;
   font-size: 20px
}

.wb-panel small {
   color: #e7272d;
   font-weight: 800;
   letter-spacing: .1em
}

.wb-panel p {
   color: #777
}

.wb-panel>a {
   color: #d41e25;
   font-weight: 800
}

.wb-panel>span {
   color: #888
}

.wb-tabs {
   display: flex;
   gap: 6px
}

.wb-tabs button {
   border: 0;
   background: #f3f3f3;
   border-radius: 15px;
   padding: 6px 11px
}

.wb-tabs button.on {
   background: #333;
   color: #fff
}

.wb-table {
   margin-top: 17px
}

.wb-tr {
   display: grid;
   /* 最后一列是操作列：原来只有 .7fr（约 100px），放两个按钮就换行、看着零碎，加宽到 1.08fr */
   grid-template-columns: 1fr 1.15fr 1.25fr .75fr .75fr 1.08fr;
   gap: 10px;
   padding: 12px 8px;
   align-items: center;
   border-bottom: 1px solid #eee
}

.wb-th {
   background: #fafafa;
   color: #777;
   font-size: 12px
}

/* 「暂无数据」统一版式 = 图标 + 提示（2026-09-29 用户要求「暂无信息能不能统一用图标加提示」）。
   一处 CSS 覆盖全部工作台的 .wb-empty（约 20 个 JS / 模板渲染点），不必逐个改渲染文案。
   图标是内联 SVG（灰线「空收件箱」），data URI 里的 `#`/`<`/`>` 必须写成 %23/%3C/%3E，否则 CSS 解析会断。 */
.wb-empty {
   text-align: center;
   color: #999;
   padding: 35px
}

.wb-empty::before {
   content: '';
   display: block;
   width: 52px;
   height: 52px;
   margin: 0 auto 12px;
   background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a8b2c0' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 13h4l1.6 2.7h4.8L16 13h4'/%3E%3Cpath d='M6.3 4.6h11.4a2 2 0 0 1 1.8 1.1l2.5 5.4v6a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-6l2.5-5.4a2 2 0 0 1 1.8-1.1Z'/%3E%3C/svg%3E") center/contain no-repeat;
   opacity: .85
}

.wb-grid {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   gap: 15px
}

.wb-grid .wb-panel {
   min-height: 155px;
   margin: 0
}

/* 概览页的模块入口卡片整卡可点（原来只有卡片里的小链接，命中区域太小）。
   卡片改成 <a> 后必须显式声明 display/颜色/下划线，否则会被全站链接样式改成蓝字带下划线。 */
a.wb-panel {
   display: block;
   color: inherit;
   text-decoration: none;
   transition: border-color .16s, box-shadow .16s
}

a.wb-panel:hover {
   box-shadow: var(--gr-card-shadow-hover) !important
}

/* 特异性要压过 .wb-panel>span{color:#888}，否则入口文案会变灰 */
a.wb-panel .panel-cta {
   display: inline-block;
   margin-top: 10px;
   color: #d41e25;
   font-weight: 800
}

a.wb-panel:hover .panel-cta {
   text-decoration: underline
}

/* 订单详情弹窗底部的操作区（确认档期/确认合作/安排发货/沟通…都从这里走）。
   按钮本身复用全站组件 ui.css 的 .gr-btn，这里只管布局。 */
.wb-detail-actions {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
   justify-content: flex-end;
   margin-top: 16px;
   padding-top: 16px;
   border-top: 1px solid #edf0f4
}

/* 列表操作列的「订单详情」是链接（跳独立详情页），尺寸与对齐见上面的合并规则 */
.wb-ops a.wb-op-link:hover {
   border-color: #c51b21;
   color: #c51b21
}

/* 买家订单详情页（/member/orders/{id}）：信息两列排、提示条、动作排 */
.od-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
   gap: 0 26px
}

.od-hint {
   margin: 0 0 14px;
   padding: 10px 12px;
   background: #f7f8fa;
   border-radius: 8px;
   color: #5a636e;
   font-size: 13px;
   line-height: 1.7
}

.od-confirm {
   display: flex;
   align-items: center;
   gap: 12px;
   flex-wrap: wrap
}

.od-actions {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
   margin-top: 14px
}

/* 聊天区嵌在面板里时，要和面板标题（「与商家沟通」）之间留出缝隙 */
.wb-panel .gr-chat {
   margin-top: 14px
}

/* 独立沟通页（/member/orders/{id}/chat、/supplier/orders/{id}/chat）：
   整页形态下聊天区要比内嵌时的 300px 高得多，否则一屏看不到几条就得翻历史。 */
.chat-page .gr-chat-list {
   height: min(60vh, 640px);
   min-height: 380px
}

@media(max-width:900px) {
   .od-grid {
      grid-template-columns: 1fr
   }
}

/* 尚未开放的功能卡片：明确标注，避免「点了没反应」的困惑 */
.wb-panel .panel-soon {
   display: inline-block;
   margin-top: 10px;
   padding: 2px 9px;
   border-radius: 10px;
   background: #f1f3f5;
   color: #8a93a0;
   font-size: 12px
}

/* ⚠️ 必须限定 `body >`：写成裸 `footer` 会命中**弹窗里的按钮行**（例如商品表单的
   #offerForm footer）—— 它被这条规则刷成站脚的深色底，但按钮文字颜色不在本规则里，
   于是弹窗底部出现一条突兀的深色横条（2026-09-23 用户报「发布租赁商品弹窗样式有 bug」）。
   页面级站脚本身是 body 直接子级，且真正生效的样式来自 .gr-market-footer / platform.css
   的 `body > footer`，所以限定作用域不会改变任何页面的外观。 */
body > footer {
   background: #20232a;
   color: #888;
   padding: 22px;
   text-align: center
}

@media(max-width:900px) {
   .wb-shell {
      grid-template-columns: 1fr
   }

   .wb-shell>aside {
      display: none
   }

   .wb-stats {
      grid-template-columns: 1fr 1fr
   }

   .wb-grid {
      grid-template-columns: 1fr 1fr
   }

   .wb-top nav {
      display: none
   }
}

@media(max-width:560px) {
   main {
      padding: 15px
   }

   .wb-top {
      padding: 0 14px
   }

   .wb-top>div a:first-child {
      display: none
   }

   .wb-welcome {
      padding: 22px
   }

   .wb-welcome p {
      display: none
   }

   .wb-stats,
   .wb-grid {
      grid-template-columns: 1fr
   }

   .wb-panel-head {
      display: block
   }

   .wb-tabs {
      margin-top: 12px;
      overflow-x: auto
   }

   .wb-th {
      display: none
   }

   .wb-tr {
      grid-template-columns: 1fr 1fr
   }
}

/* 商品弹窗原来自带 <header>（<dialog id="offerDialog">），需要按 id 压 platform.css 的
   全局 header{background/box-shadow!important}；现在壳统一为 GRUI.dialog，
   标题条是 .gr-dialog-head 这个 div，不会再被 header 规则命中，该覆盖已不需要。 */

/* ---------- 订单列表：状态标签 + 操作按钮 ---------- */
/* 以前 .wb-tr button 没有任何规则，操作列渲染的是浏览器默认灰按钮，多个挤在一起很难看 */
.wb-ops {
   display: flex;
   flex-wrap: wrap;
   gap: 6px;
   align-items: center;
   justify-content: flex-end;
   /* width: max-content 只负责「一行放得下时并排」；必须再配 max-width: 100%，
      否则这个盒子恒定 578px，在窄右列里向左溢出盖住标题列，flex-wrap 永远不会触发。
      右列宽度由上面 .od-card 的 minmax(0, 55%) 给成确定值，所以 100% 有解。 */
   width: max-content;
   max-width: 100%
   }


   /* 操作列里既有 <button> 也有 <a>（订单详情是跳转链接）：两者必须同尺寸、同一套对齐，
   否则 <a> 是行内元素、文字会贴顶不居中，看着和旁边的按钮不齐。
   ⚠️ display / min-height 必须 !important：commerce.css 由 writeRobotHTML 注入在
   workbench.css **之后**，而它的 `body [type=button]{display:inline-flex;min-height:42px}`
   与 `.wb-ops button` 权重相同（都是 0,1,1），同权重下后者（commerce）胜出 —— 不覆盖的话
   <button> 是 42px 高、<a> 只有 30px，同一个操作列里两种高度。同类处理见
   .order-status-tabs button 与 ui.css 的 .gr-select-trigger。 */
.wb-ops button,
.wb-ops a.wb-op-link {
   display: inline-flex !important;
   align-items: center;
   justify-content: center;
   box-sizing: border-box;
   /* 宽度写死（不是 min-width）：「订单详情」（4 字）与「完成服务并发起验收」（9 字，最长）
      必须一样大，宽度随文案变就不叫一样大了。140px 是按 9 字 × 12px + 左右 12px 内边距
      + 2px 边框留出余量定的。 */
   width: 140px;
   flex: 0 0 auto;
   min-height: 30px !important;
   padding: 0 12px;
   border: 1px solid #d8dbe0;
   border-radius: 6px;
   background: #fff;
   color: #313a46;
   font-size: 12px;
   line-height: 1;
   white-space: nowrap;
   cursor: pointer
}

/* ⚠️ 操作列里现在有两套按钮体系，hover 必须分开：
   ① 页面自有按钮（data-variant=primary/danger/muted）—— 由下面的 variant 规则接管；
   ② 全站组件按钮（.gr-btn / .gr-btn.primary，发票页等新页面在用）—— 自带 ui.css 的红底白字。
   这条 generic hover **只改 color 不改 background**（(0,3,1) 压得过 .gr-btn.primary 的 (0,2,0)），
   一旦命中红底的主按钮就变成「红底红字」→ 悬停时文字像消失了
   （2026-09-24 用户报：发票页「开票」按钮鼠标放上去不显示字体）。故排除 .gr-btn。 */
.wb-ops button:hover:not(:disabled):not(.gr-btn) {
   border-color: #c51b21;
   color: #c51b21
}

/* 全站组件按钮在操作列里的 hover（对齐 ui.css 的红主色；取值与 data-variant 那套一致）：
   次要按钮 = 加深描边与字色、保持白底；主按钮 = 加深底色、白字不动。 */
.wb-ops button.gr-btn:hover:not(:disabled) {
   border-color: #c51b21;
   color: #c51b21
}

.wb-ops button.gr-btn.primary:hover:not(:disabled) {
   border-color: #a9161b;
   background: #a9161b;
   color: #fff
}

/* 操作列的排序只分三档（order 生效于 .wb-ops 这个 flex 容器，不改 DOM，键盘 Tab 顺序不变）：
   0 链接/不可点的状态提示 → 1 次要操作（含「取消订单」）→ 2 主操作。
   一行从左到右就是：订单详情、联系买家 → 次要操作 → 主操作，**重要的按钮永远在最右**。 */
.wb-ops a.wb-op-link,
.wb-ops button:disabled {
   order: 0
}

.wb-ops button {
   order: 1
}

.wb-ops button[data-variant="primary"] {
   order: 2;
   border-color: #c51b21;
   background: #c51b21;
   color: #fff
}

.wb-ops button[data-variant="primary"]:hover:not(:disabled) {
   background: #a9161b;
   border-color: #a9161b;
   color: #fff
}

/* 动作清单里的 <a>（href 项）也可能是主操作：「再次租赁」= 已取消订单卡片，2026-09-29 用户要求标红。
   原来 <a> 只有白底描边一种样式，这里让带 data-variant="primary" 的链接对齐上面的
   button[data-variant="primary"]（红底白字 + order 2 排到最右）。⚠️ hover 必须显式覆盖
   .wb-ops a.wb-op-link:hover 的红字（(0,3,1) 会命中红底 → 红底红字，文字像消失，
   与 2026-09-24 发票页「开票」按钮踩过的坑同一个）。 */
.wb-ops a.wb-op-link[data-variant="primary"] {
   order: 2;
   border-color: #c51b21;
   background: #c51b21;
   color: #fff
}

.wb-ops a.wb-op-link[data-variant="primary"]:hover {
   border-color: #a9161b;
   background: #a9161b;
   color: #fff
}

.wb-ops button[data-variant="danger"] {
   border-color: #e3bcbc;
   color: #b5252b
}

.wb-ops button[data-variant="danger"]:hover:not(:disabled) {
   border-color: #b5252b;
   background: #fdf3f3
}

/* 「取消订单」是次要操作，用户 2026-09-23 要求不要红色：muted 保持中性描边灰，
   hover 也给灰反馈（不落到上面 .wb-ops button:hover 那条红边框/红字上）。
   danger 只留给「申请退款」等真正的破坏性动作。 */
.wb-ops button[data-variant="muted"] {
   border-color: #d8dbe0;
   background: #fff;
   color: #313a46
}

.wb-ops button[data-variant="muted"]:hover:not(:disabled) {
   border-color: #c3c8cf;
   background: #f6f7f9;
   color: #313a46
}

.wb-ops button:disabled {
   opacity: .55;
   cursor: not-allowed
}

.wb-status {
   display: inline-block;
   padding: 2px 9px;
   border-radius: 10px;
   font-size: 12px;
   line-height: 1.7;
   white-space: nowrap;
   background: #f1f3f5;
   color: #5a636e
}

.wb-status[data-tone="wait"] {
   background: #fff4e5;
   color: #8a5a00
}

.wb-status[data-tone="doing"] {
   background: #eaf3ff;
   color: #1b4f86
}

.wb-status[data-tone="done"] {
   background: #eaf7ef;
   color: #1a6b3c
}

.wb-status[data-tone="warn"] {
   background: #fdeeee;
   color: #a32027
}

/* ---------- 通用弹窗（订单详情 / 履约进度 / 选支付方式）的壳已统一到全站组件 ----------
   弹窗骨架在 ui.css（.gr-dialog 系列），收银台专有样式在 pay-dialog.css（.wb-pay-*）；
   两者都由全站注入，确认订单页共用同一份，本页不再定义弹窗壳样式。 */

.wb-detail-top {
   display: flex;
   gap: 14px;
   align-items: center;
   padding: 14px 16px;
   background: #f7f8fa;
   border-radius: 12px;
   margin-bottom: 16px
}

.wb-detail-top b,
.wb-detail-top small,
.wb-detail-top span {
   display: block
}

.wb-detail-top b {
   font-size: 16px
}

.wb-detail-top small {
   margin: 3px 0 7px;
   color: #5f6874
}

.wb-detail-cover {
   width: 76px;
   height: 76px;
   object-fit: cover;
   border-radius: 10px
}

.wb-detail-block {
   border: 1px solid #edf0f4;
   border-radius: 12px;
   padding: 12px 16px;
   margin-bottom: 14px
}

.wb-detail-block h3 {
   margin: 0 0 8px;
   font-size: 15px
}

.wb-detail-block p {
   margin: 5px 0;
   color: #4c5461;
   font-size: 13px
}

.wb-detail-row {
   display: flex;
   justify-content: space-between;
   gap: 16px;
   padding: 7px 0;
   border-bottom: 1px solid #f2f4f7;
   font-size: 13px
}

.wb-detail-row:last-child {
   border-bottom: 0
}

.wb-detail-row span {
   color: #5f6874
}

.wb-detail-row b {
   text-align: right;
   word-break: break-all
}

.wb-detail-empty,
.wb-detail-note {
   padding: 14px;
   background: #f7f8fa;
   border-radius: 10px;
   color: #5a636e;
   font-size: 13px
}

.wb-detail-events>div {
   display: flex;
   gap: 10px;
   padding: 6px 0
}

.wb-detail-events i {
   width: 8px;
   height: 8px;
   margin-top: 6px;
   border-radius: 50%;
   background: #c51b21;
   flex-shrink: 0
}

.wb-detail-events b,
.wb-detail-events small {
   display: block;
   font-size: 13px
}

.wb-detail-events small {
   color: #5f6874
}

/* 选支付方式 / 扫码支付（.wb-pay-choices、.wb-pay-qr*、等待与完成态）见 pay-dialog.css */

/* 履约进度时间线：原先内联在 buyer-workbench.js 里，挪到样式表统一维护 */
.fd-timeline {
   display: grid;
   /* 列数不写死：送货型 7 步（多一步「待收货」）、到场型 6 步、列表页履约弹窗 6 步。
      原来写死 repeat(6,1fr)，第 7 个步骤会掉到第二行；而 .fd-step:after 的连接线是
      相对本格定位（left:-50%），换行后连线也会接到上一行的格子上去。 */
   grid-auto-flow: column;
   grid-auto-columns: 1fr;
   margin: 12px 0 20px
}

.fd-step {
   text-align: center;
   position: relative;
   color: #5f6874;
   font-size: 13px
}

.fd-step:before {
   content: '';
   display: block;
   width: 18px;
   height: 18px;
   border: 3px solid #d9dee6;
   background: #fff;
   border-radius: 50%;
   margin: 0 auto 8px;
   position: relative;
   z-index: 2
}

.fd-step:after {
   content: '';
   position: absolute;
   top: 9px;
   left: -50%;
   width: 100%;
   height: 2px;
   background: #d9dee6
}

.fd-step:first-child:after {
   display: none
}

.fd-step.done,
.fd-step.active {
   color: #c51b21;
   font-weight: 700
}

.fd-step.done:before,
.fd-step.active:before {
   border-color: #c51b21;
   background: #c51b21
}

.fd-step.done:after,
.fd-step.active:after {
   background: #c51b21
}

@media (max-width:650px) {
   .wb-ops {
      justify-content: flex-start
   }

   .fd-timeline {
      /* 窄屏改回按行流：grid-auto-flow 必须显式覆盖，否则会按列流排在显式 3 列之外 */
      grid-auto-flow: row;
      grid-template-columns: repeat(3, 1fr);
      gap: 18px 0
   }

   /* 每行第一个不画连接线：3 列时是第 1、4、7 个（7 步时间线的最后一行只有一个「已完成」） */
   .fd-step:nth-child(4):after,
   .fd-step:nth-child(7):after {
      display: none
   }
}

/* ---------- 订单卡片列表（采购工作台 /member/buyer 与厂家经营台 /supplier/orders 共用） ----------
   列表原来是六列表格，手机号、商品名、金额都被压成一行；改成卡片后每单一块，
   左侧商品图、中间订单摘要、右侧状态与金额、操作按钮。 */
.od-cards {
   margin-top: 14px
}

.od-card {
   display: grid;
   /* 第三列（状态 / 金额 / 操作）必须用百分比封顶，**不能**用 auto：
      auto 轨道按 max-content 取值，而操作列是 4 个固定 140px 的按钮
      （「订单详情」「联系商家」+ 最多 2 个状态动作 = 578px），窄窗口下这 578px 会把中间的标题列
      一路挤到 0～18px —— 1280 窗口标题就开始逐字换行，1024 窗口卡片被撑到 1383px 高。
      封顶 55% 后：≥1403px 窗口操作按钮仍并排一行（578 放得下），窗口更窄时按钮自己折成两行，
      标题列永远至少能拿到 45% 的宽度。 */
   grid-template-columns: 104px minmax(0, 1fr) minmax(0, 55%);
   gap: 16px;
   padding: 16px;
   border: 0;
   border-radius: 12px;
   background: #fff;
   margin-bottom: 12px;
   box-shadow: var(--gr-card-shadow);
   transition: border-color .16s, box-shadow .16s;
   /* 整张卡片可点进订单详情（跳转由列表脚本的点击代理处理） */
   cursor: pointer
}

.od-card:last-child {
   margin-bottom: 0
}

.od-card:hover {
   box-shadow: var(--gr-card-shadow-hover)
}

.od-card-cover {
   width: 104px;
   height: 104px;
   object-fit: cover;
   border-radius: 10px;
   background: #f2f4f7;
   display: block
}

.od-card-main {
   min-width: 0
}

.od-card-main b {
   display: block;
   font-size: 16px;
   margin-bottom: 6px
}

.od-card-main b a:hover {
   color: #c51b21
}

.od-card-sub {
   color: #5f6874;
   font-size: 13px;
   margin-bottom: 4px;
   word-break: break-all
}

.od-card-meta {
   display: flex;
   flex-wrap: wrap;
   gap: 6px 14px;
   color: #5f6874;
   font-size: 13px;
   margin-top: 8px
}

.od-card-side {
   display: flex;
   flex-direction: column;
   align-items: flex-end;
   justify-content: space-between;
   gap: 8px;
   min-width: 172px
}

.od-card-price {
   color: #c51b21;
   font-size: 18px;
   font-weight: 900
}

/* ---------- 订单列表顶部的状态筛选标签 ----------
   沿用 .wb-tabs 的胶囊观感，但 commerce.css 有一条带 !important 的
   body button{display:inline-flex;min-height:42px}，不用 !important 覆盖回来每个标签会被撑成 42px 高。 */
/* gap / row-gap 是为右上角的数字徽标（.gr-dot，GRUI.dot）留位：徽标会溢出标签右上角约 7-8px，
   间距不够时会压到右边的标签、换行时压到上一行。不能沿用 .wb-tabs 的 6px。
   ⚠️ 这条与 .wb-tabs 的特异性相同（都是 0,1,0），现在靠「本文件里排在后面」才生效 ——
   改顺序或删掉 gap 会静默退回 6px（于是徽标压到右邻）。所以选择器写成两个类。 */
/* ≤560px 时 .wb-tabs 会变成 overflow-x:auto 的横向滚动容器（此时 overflow-y 也被计算为 auto），
   首行徽标向上溢出约 9px 会被裁掉、末列还会顶出横向滚动条 —— 带红点的标签行都不参与横向滚动
   （订单状态标签 + 买家发票页的状态筛选，两处的计数都是标签右上角的 .gr-dot）。 */
@media (max-width: 560px) {
    .wb-tabs.order-status-tabs,
    .wb-tabs.invoice-tabs {
        overflow: visible;
        padding-top: 10px
    }
}

.wb-tabs.order-status-tabs,
.wb-tabs.invoice-tabs {
   gap: 9px;
   row-gap: 16px;
   flex-wrap: wrap
}

.wb-tabs.order-status-tabs {
   margin-top: 14px
}

/* 商家发票页（/supplier/invoices）的页签用的是 .merchant-tabs（定义在 merchant-commerce.css：
   gap 8px、不换行）—— 2026-09-29 它的计数也改成标签右上角的数字红点，同样要为徽标留位。
   ⚠️ 选择器带 #invoiceTabs 限定：.merchant-tabs 是通用类，商品列表的 #offerTabs 等也在用，
   直接改类会连它们一起变（那些页的计数是 <em>、没有徽标）。 */
.merchant-tabs#invoiceTabs {
   gap: 9px;
   row-gap: 16px;
   flex-wrap: wrap
}

.order-status-tabs button {
   display: inline-flex !important;
   align-items: center;
   min-height: 30px !important;
   padding: 0 12px !important;
   border: 1px solid #e6e9ee !important;
   border-radius: 15px;
   background: #fff !important;
   color: #5a636e !important;
   font-size: 13px !important;
   font-weight: 400 !important;
   line-height: 1;
   cursor: pointer
}

.order-status-tabs button:hover {
   border-color: #c51b21 !important;
   color: #c51b21 !important
}

.order-status-tabs button.on {
   border-color: #c51b21 !important;
   background: #c51b21 !important;
   color: #fff !important;
   font-weight: 700 !important
}

/* ---------- 消息中心（/member/messages，member-messages.js） ----------
   通知与交易会话共用 .msg-row（左侧未读圆点 + 主区标题/正文 + 右侧时间/状态）；
   未读用 .unread 加重标题并把圆点染红；会话行是 <a>，hover 给底色。 */
.msg-tabs button b {
   margin-left: 5px;
   font-size: 12px;
   font-weight: 700;
   color: #c51b21
}

.msg-tabs button.on b {
   color: #fff
}

.msg-row {
   display: flex;
   align-items: flex-start;
   gap: 10px;
   padding: 14px 4px;
   border-bottom: 1px solid #f1f3f6;
   color: inherit;
   text-decoration: none
}

.msg-row:last-child {
   border-bottom: 0
}

.msg-row.conv:hover {
   background: #fafbfc
}

.msg-dot {
   flex: 0 0 auto;
   width: 8px;
   height: 8px;
   margin-top: 6px;
   border-radius: 50%;
   background: #dfe3e9
}

.msg-row.unread .msg-dot {
   background: #e51c23
}

.msg-main {
   flex: 1 1 auto;
   min-width: 0
}

.msg-title {
   display: flex;
   align-items: center;
   gap: 8px;
   font-size: 14px;
   font-weight: 700;
   color: #313a46
}

.msg-title em {
   font-style: normal;
   font-size: 12px;
   font-weight: 400;
   color: #8a939e
}

.msg-body {
   display: -webkit-box;
   margin: 4px 0 0;
   overflow: hidden;
   color: #5f6a76;
   font-size: 13px;
   line-height: 1.6;
   -webkit-box-orient: vertical;
   -webkit-line-clamp: 2
}

.msg-side {
   flex: 0 0 auto;
   display: flex;
   flex-direction: column;
   align-items: flex-end;
   gap: 4px;
   color: #8a939e;
   font-size: 12px
}

.msg-side em {
   font-style: normal
}

.msg-row.unread .msg-title {
   color: #111
}

/* ---------- 发票管理页（/member/invoices，member-invoices.js） ----------
   列表已改成与订单列表同款的 .od-card 卡片（2026-09-24），不再是 .wb-table 表格；
   这里只留两张发票页各自需要的东西：详情弹窗的键值列表。
   （原先的 `.wb-table .wb-tr em.inv-item` 是表格版的第二行小字样式，卡片化后已无任何产出点，删。）
   买家页的页签计数原本是标签里的 <b>数字</b>（.invoice-tabs button b / button.on b）——
   2026-09-29 改成标签右上角的数字红点（GRUI.dot + .gr-dot-host）后这两条已无产出点，随改版删除；
   徽标需要的间隙由上面的 .wb-tabs.invoice-tabs（与 .order-status-tabs 同一份规则）提供。
   ⚠️ 商家页（/supplier/invoices）用的是 .merchant-tabs，不受这里影响。 */

/* 发票文件预览（买家发票详情弹窗，已开票才有）：把发票本体渲染在字段列表**上方** ——
   图片直接 <img>，PDF 用 <iframe>（浏览器自带阅读器）。买家先看内容，再决定要不要下载
   （2026-09-24 用户：「应该先预览 然后有下载发票的按钮」）。 */
.inv-preview {
   margin-bottom: 14px
}

.inv-preview-img {
   display: block;
   width: 100%;
   max-height: 420px;
   object-fit: contain;
   border: 1px solid #e6e9ee;
   border-radius: 10px;
   background: #fafbfc
}

.inv-preview-frame {
   display: block;
   width: 100%;
   height: 420px;
   border: 1px solid #e6e9ee;
   border-radius: 10px;
   background: #fff
}

.invoice-detail {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
   gap: 14px
}

.invoice-detail>div {
   display: flex;
   flex-direction: column;
   gap: 3px;
   min-width: 0
}

.invoice-detail small {
   color: #8a939e;
   font-size: 12px
}

.invoice-detail b {
   font-size: 14px;
   font-weight: 600;
   word-break: break-all
}

@media (max-width: 640px) {
   .invoice-detail {
      grid-template-columns: minmax(0, 1fr)
   }
}

/* ---------- 订单详情：商品卡片 ---------- */
.od-goods {
   display: flex;
   gap: 16px;
   align-items: flex-start;
   margin-top: 14px
}

.od-goods-cover {
   width: 132px;
   height: 132px;
   object-fit: cover;
   border-radius: 12px;
   background: #f2f4f7;
   flex-shrink: 0
}

.od-goods-body {
   min-width: 0;
   flex: 1
}

.od-goods-body>b {
   display: block;
   font-size: 16px;
   margin-bottom: 10px
}

.od-goods-facts {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
   gap: 0 26px
}

/* 「可退押金（平台托管）」里的托管说明：浅绿字，与金额和其它字段区分开 */
.od-trust {
   color: #4cb782;
   font-weight: 600
}

/* ---------- 订单详情：确认档期内嵌的沟通入口 ---------- */
.od-chat {
   margin-top: 14px;
   padding-top: 14px;
   border-top: 1px dashed #e6e9ee
}

.od-chat .wb-detail-note {
   margin: 0 0 12px
}

/* ---------- 订单详情：履约进度（纵向步骤，取代原来的横向时间线 + 独立订单时间线卡片） ----------
   每步 = 标题 + 说明 + 完成时间；已完成/进行中的步骤用主色圆点，最后的已完成步骤不画连接线。 */
.od-flow-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   padding: 10px 12px;
   background: #f7f8fa;
   border-radius: 8px;
   margin-top: 14px
}

.od-flow-head b {
   font-size: 14px
}

.od-flow-head span {
   color: #6b7480;
   font-size: 12px
}

.od-flow {
   margin-top: 16px
}

.od-flow-step {
   position: relative;
   padding: 0 0 20px 30px
}

.od-flow-step:before {
   content: '';
   position: absolute;
   left: 5px;
   top: 5px;
   width: 12px;
   height: 12px;
   border: 2px solid #d9dee6;
   border-radius: 50%;
   background: #fff;
   z-index: 2
}

.od-flow-step:after {
   content: '';
   position: absolute;
   left: 10px;
   top: 21px;
   bottom: 0;
   width: 2px;
   background: #e6e9ee
}

.od-flow-step:last-child {
   padding-bottom: 0
}

.od-flow-step:last-child:after {
   display: none
}

.od-flow-step b {
   display: block;
   font-size: 14px;
   color: #6b7480
}

.od-flow-step p {
   margin: 3px 0 0;
   color: #6b7480;
   font-size: 12px;
   line-height: 1.6
}

.od-flow-step small {
   display: block;
   margin-top: 4px;
   color: #6b7480;
   font-size: 12px
}

.od-flow-step.done:before,
.od-flow-step.active:before {
   border-color: #c51b21;
   background: #c51b21
}

.od-flow-step.done:after {
   background: #c51b21
}

/* ---------- 订单详情：押金进度（gr_deposit_ledger 流水：托管 / 损坏扣款 / 退还） ----------
   商家归还验机定损后，扣款金额、损坏说明与凭证都落在这张卡里，买家与商家两页共用这套样式。 */
.od-ledger {
   display: grid;
   gap: 10px
}

.od-ledger-item {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 18px;
   padding: 12px 14px;
   border: 1px solid #edf0f4;
   border-radius: 10px;
   background: #fafbfc
}

.od-ledger-main {
   min-width: 0
}

.od-ledger-main b {
   display: block;
   font-size: 14px
}

.od-ledger-main small {
   display: block;
   margin-top: 4px;
   color: #6b7480;
   font-size: 12px;
   line-height: 1.6;
   word-break: break-all
}

/* 售后进度的一条工单会有 3~4 行小字（工单号 / 提交 / 新租期 / 处理于），
   逐行 4px 间距太散，收紧到 2px；关键值（改期·延租后的新租期）用与「已完成」徽标同一支绿，
   让它从一堆灰色小字里跳出来。 */
.od-ledger-main small + small {
   margin-top: 2px
}

.od-as-hi {
    color: #1a6b3c;
    font-weight: 700
}

/* 售后工单里的金额（退款 / 赔偿）：红字加粗，与「新租期」的绿字（.od-as-hi）同级 ——
   两者都是这条工单里最该被一眼看到的值，其余（工单号 / 提交时间）保持灰色小字。 */
.od-as-amount {
    color: #c51b21;
    font-weight: 700
}

.od-ledger-side {
   display: flex;
   flex: none;
   align-items: center;
   gap: 10px
}

.od-ledger-side b {
   font-size: 15px
}

/* 「交付与物流」卡里运单号 / 联系电话后面的「复制」（对齐小程序，2026-09-23）：
   值本身渲染在 .wb-detail-row 的 <b> 里（加粗），复制链接要压回常规字重。 */
.wb-detail-row .od-copy {
   margin-left: 8px;
   font-size: 12px;
   font-weight: 400;
   color: var(--gr-link, #005ea7);
   text-decoration: none;
   cursor: pointer
}

.wb-detail-row .od-copy:hover {
   text-decoration: underline
}

/* 验机凭证缩略图沿用售后工单那套 .merchant-evidence（merchant-commerce.css），
   这里只把「点开原图」的 <a> 撑满缩略图格子。 */
.od-evidence {
   margin-top: 14px
}

.merchant-evidence-item a {
   display: block;
   width: 100%;
   height: 100%
}

.od-flow-step.done b,
.od-flow-step.active b {
   color: #1f2329
}

.od-flow-step.active:before {
   box-shadow: 0 0 0 4px #c51b211f
}

.od-flow-step.done small,
.od-flow-step.active small {
   color: #5f6874
}

@media(max-width:760px) {
   .od-card {
      grid-template-columns: 80px minmax(0, 1fr)
   }

   .od-card-cover {
      width: 80px;
      height: 80px
   }

   .od-card-side {
      grid-column: 1 / -1;
      align-items: flex-start;
      flex-direction: row;
      flex-wrap: wrap;
      min-width: 0
   }

   .od-goods {
      flex-direction: column
   }

   .od-goods-facts {
      grid-template-columns: 1fr
   }
}

/* ---------- 改期审核（/supplier/schedule-reviews，supplier-workbench.js 的 scheduleCard） ----------
   版式参照小程序端「改期审核」：单号 + 状态 → 商品与订单 → 原档期 ↓ 新档期 → 原因 → 提示 → 差价 → 操作。
   ⚠️ 这是供应商侧唯一的「有待审核订单」提示：侧边栏角标 .wb-nav-badge。 */
/* ⚠️ 三条必须同时在位，少一条就会出现「只剩一个没有数字的小红点」：
   ① `.wb-nav-badge[hidden]` 必须显式写：作者样式里的 display 会顶掉 UA 的 `[hidden]{display:none}`，
      否则待审为 0 / 接口失败时（JS 置 hidden=true），空角标照样是个实心红点，永远挂在那里；
   ② 用 line-height 定高居中，不用 flex 居中 —— 外部规则一旦改了 line-height，flex 里的数字会被裁；
   ③ 常态（深色底）红底白字；选中/悬停是红底，红底上再放红角标等于看不见 → 反白。 */
.wb-nav-badge {
   display: inline-block;
   min-width: 18px;
   height: 18px;
   margin-left: 6px;
   padding: 0 6px;
   border-radius: 9px;
   background: #e7272d;
   color: #fff;
   font-size: 12px;
   font-weight: 700;
   line-height: 18px;
   text-align: center;
   vertical-align: 1px
}

.wb-nav-badge[hidden] {
   display: none
}

/* 选中与悬停都是红底，红底上再放红角标等于看不见 → 一律反白 */
.wb-shell aside a.on .wb-nav-badge,
.wb-shell aside a:hover .wb-nav-badge {
   background: #fff;
   color: #c51b21
}

/* 计数已改成标签右上角的数字徽标（GRUI.dot + .gr-dot-host，见 ui.css），所以原来给
   「标签里那个 <b>数字</b>」写的 .schedule-tabs button b / button.on b 两条规则随改版删除。
   徽标需要的间隙由 .wb-tabs.order-status-tabs 提供（gap 9px、row-gap 16px、≤560px overflow:visible），
   与订单列表状态标签是同一份规则，不必在此重复。 */

.schedule-tabs {
   margin-bottom: 4px
}

.sr-card {
   margin-bottom: 14px;
   padding: 16px 18px;
   border: 0;
   border-radius: 12px;
   background: #fff;
   box-shadow: var(--gr-card-shadow)
}

.sr-card:last-child {
   margin-bottom: 0
}

.sr-card:hover {
   box-shadow: var(--gr-card-shadow-hover)
}

.sr-head {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px
}

.sr-no {
   display: flex;
   align-items: center;
   gap: 9px;
   min-width: 0
}

.sr-no b {
   font-size: 15px
}

.sr-no a:hover {
   color: #c51b21
}

.sr-submit {
   flex: none;
   color: #8a8f98;
   font-size: 12px
}

.sr-body {
   display: flex;
   gap: 14px;
   margin-top: 13px
}

.sr-cover {
   flex: none;
   width: 72px;
   height: 72px;
   border-radius: 9px;
   background: #f3f4f6;
   object-fit: cover
}

.sr-main {
   flex: 1;
   min-width: 0
}

.sr-main > b {
   display: block;
   font-size: 15px
}

.sr-main > p {
   margin: 5px 0 0;
   color: #5f6874;
   font-size: 13px
}

/* 原档期 → 新档期：新档期用主色强调（小程序端同样是红字） */
.sr-window {
   display: flex;
   align-items: center;
   gap: 12px;
   margin-top: 10px;
   padding: 10px 12px;
   border-radius: 9px;
   background: #f7f8fa
}

.sr-window div {
   display: flex;
   flex-direction: column;
   gap: 3px
}

.sr-window span {
   color: #8a8f98;
   font-size: 12px
}

.sr-window b {
   font-size: 14px
}

.sr-window b.next {
   color: #c51b21
}

.sr-window i {
   color: #b6bcc6;
   font-style: normal
}

.sr-hint {
   margin-top: 12px;
   padding: 10px 12px;
   border-radius: 9px;
   background: #fdf6e8;
   color: #8a5a00;
   font-size: 13px;
   line-height: 1.6
}

.sr-hint b {
   display: block;
   margin-bottom: 2px
}

.sr-hint p {
   margin: 0
}

.sr-hint.blocked {
   background: #fdeeee;
   color: #a32027
}

.sr-diff {
   display: flex;
   align-items: baseline;
   flex-wrap: wrap;
   gap: 8px;
   margin-top: 10px;
   font-size: 13px
}

.sr-diff span {
   color: #8a8f98
}

.sr-diff b {
   color: #1a6b3c
}

.sr-diff em {
   color: #8a8f98;
   font-size: 12px;
   font-style: normal
}

.sr-ops {
   margin-top: 14px
}

/* ---------- 客户会话（/supplier/conversations，supplier-conversations.js） ----------
   行结构与消息中心（/member/messages）的会话行**同一套** .msg-row / .msg-main / .msg-title /
   .msg-body / .msg-side（通知与会话共用一份行结构），这里只补商家侧会话列表特有的两样：
     · .conv-avatar —— 客户名首字方块，给行左侧一个稳定宽度（对齐小程序商家版会话列表的观感）；
     · .conv-flag   —— 行尾「客户消息」= 最后一条来自客户（**不是**未读数，接口没有读态字段）。 */
.conv-avatar {
   flex: 0 0 auto;
   display: flex;
   width: 40px;
   height: 40px;
   align-items: center;
   justify-content: center;
   border-radius: 10px;
   background: #fff1f1;
   color: #c51b21;
   font-size: 16px;
   font-weight: 700
}

.conv-flag {
   color: #c51b21;
   font-weight: 700
}
/* ===== 机器人产品管理（/supplier/offers）列表：2026-09-24 按原型 pc-mc-goods.html 改成表格 =====
   只加这一页需要的东西，表格骨架复用 .wb-table / .wb-tr / .wb-th（见本文件上方），
   原型那套 bk-* 样式一律不引入（同一个工作台并存两套设计系统比任何一套单独都差）。 */
.offer-head-right {
    display: flex;
    align-items: center;
    gap: 12px
}

.offer-head-right b {
    color: #777;
    font-size: 13.5px;
    font-weight: 600
}

.offer-new {
    display: inline-flex;
    align-items: center;
    height: 34px;
    padding: 0 14px;
    border-radius: 8px;
    background: linear-gradient(135deg, #ff6b5b, #e7272d);
    color: #fff;
    font-size: 13.5px;
    font-weight: 700;
    white-space: nowrap
}

.offer-new:hover {
    color: #fff;
    filter: brightness(1.04)
}

/* 页签计数：.merchant-tabs 的样式在别处，这里只给本页页签里的 <em> 计数加样式（选择器带 id，不外泄） */
#offerTabs em {
    margin-left: 6px;
    font-style: normal;
    font-size: 12px;
    font-weight: 700;
    opacity: .8
}

/* 筛选栏：一行铺开，窄屏自动换行（与工作台其它页一致的 4 列节奏） */
.offer-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px 14px;
    margin: 16px 0 4px
}

.offer-filter label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 148px
}

/* 搜索框排在最前、且比下拉窄（用户 2026-09-24：输入框放「应用场景」前面，宽度小一些） */
.offer-filter label.narrow {
    flex: 0 0 auto;
    width: 190px;
    min-width: 150px
}

.offer-filter label>span {
    color: #777;
    font-size: 12.5px;
    font-weight: 600
}

.offer-filter select,
.offer-filter input {
    height: 36px;
    border: 1px solid #e3e3e3;
    border-radius: 8px;
    padding: 0 11px;
    font-size: 13.5px;
    color: #333;
    background: #fff
}

.offer-filter input {
    width: 100%
}

.offer-reset {
    height: 36px;
    padding: 0 15px;
    border: 1px solid #e3e3e3;
    border-radius: 8px;
    background: #fff;
    color: #555;
    font-size: 13.5px;
    font-weight: 600
}

.offer-reset:hover {
    border-color: #ffc9c4;
    color: #e7272d
}

/* 表格：列多，窄屏横向滚动而不压成一坨（照 .mb-table 的做法） */
.offer-table {
    overflow-x: auto
}

.offer-table .wb-tr {
    grid-template-columns: minmax(190px, 1.5fr) 1.05fr .85fr 1.05fr .95fr .75fr .7fr .6fr .8fr .75fr 1.5fr;
    min-width: 1180px
}

.offer-main-cell {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0
}

.offer-main-cell b {
    font-weight: 700;
    color: #222;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap
}

/* 应用场景 / 服务地区这两列也可能是长文本（服务地区最多 20+ 个城市）：单行省略 + 完整内容走 title 浮窗。
   ⚠️ 不要改成自绘浮窗：单元格自身 overflow:hidden、表格外层 overflow-x:auto，两层都会把浮窗裁掉。
   overflow:hidden 同时让 grid 项可以收缩到 min-content 以下（否则 1fr 轨道会被长内容顶宽）。 */
.offer-table .wb-tr>.offer-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap
}

.offer-thumb {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    object-fit: cover;
    background: #f4f4f6;
    flex: 0 0 auto
}

.offer-thumb-none {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #e7272d;
    background: #fdeded;
    font-weight: 800
}

.offer-status {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 6px;
    font-size: 12.5px;
    font-weight: 700;
    font-style: normal;
    background: #f4f4f6;
    color: #666
}

.offer-status.published {
    background: #eaf7ee;
    color: #1f8a4c
}

.offer-status.pending_review {
    background: #fff4e5;
    color: #b26a00
}

.offer-status.draft {
    background: #eef2ff;
    color: #3f51b5
}

.offer-status.offline {
    background: #f4f4f6;
    color: #777
}

.offer-status.rejected {
    background: #fdeded;
    color: #d92020
}

/* ---------- 设备台账卡片（/supplier/assets）的状态标签 ----------
   复用 .offer-status 的底座（内边距 / 圆角 / 字号），只补设备那几种状态的颜色：
   可租=绿、在租（含已锁定/使用中）=蓝、维修中=橙、已退役=灰。
   ⚠️ 与商品状态（draft/published/offline/rejected）不重名，所以直接挂在同一个类上。 */
.offer-status.available {
    background: #eaf7ee;
    color: #1f8a4c
}

.offer-status.rented,
.offer-status.in_use,
.offer-status.reserved {
    background: #eef2ff;
    color: #3f51b5
}

.offer-status.maintenance {
    background: #fff4e5;
    color: #b26a00
}

.offer-status.retired {
    background: #f4f4f6;
    color: #777
}

/* 「新增 / 编辑设备」弹窗里的口径说明（表单下方那行灰字） */
.asset-form-note {
    margin: 4px 0 0;
    color: #8b95a5;
    font-size: 12.5px;
    line-height: 1.7
}

/* 商品列表「库存上限」那一格的补充说明（第二行小字）：
   未录设备用橙色提醒补录，已录设备用灰色标出台数 —— 两页（租赁商品 / 实体设备台账）
   同一套数字，商家不用在两个页面之间对账。 */
.offer-table .cell-warn,
.offer-table .cell-sub {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    font-style: normal;
    white-space: nowrap
}

.offer-table .cell-warn {
    color: #b26a00;
    font-weight: 700
}

.offer-table .cell-sub {
    color: #8b95a5;
    font-weight: 400
}

/* 设备卡片副标题里的「待补录」（新增商品时自动录入的设备序列号为空，提示商家回来补）。
   ⚠️ 不能直接复用 .offer-table .cell-warn：它是 display:block 的表格单元格口径，
   放进卡片副标题会把那一行撑成两行。 */
.od-card .cell-warn {
    color: #b26a00;
    font-style: normal;
    font-weight: 700
}

.offer-ops {
    display: flex;
    flex-wrap: wrap;
    gap: 6px
}

.offer-ops button {
    height: 30px;
    padding: 0 11px;
    border: 1px solid #e3e3e3;
    border-radius: 7px;
    background: #fff;
    color: #444;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap
}

.offer-ops button:hover {
    border-color: #ffc9c4;
    color: #e7272d
}

.offer-ops button.primary {
    border-color: transparent;
    background: linear-gradient(135deg, #ff6b5b, #e7272d);
    color: #fff
}

.offer-ops button.primary:hover {
    color: #fff;
    filter: brightness(1.04)
}

@media (max-width: 900px) {
    .offer-filter label {
        min-width: 130px
    }

    .offer-filter label.narrow {
        width: 100%
    }
}

/* ===== 商品新增 / 编辑独立页（/supplier/offers/new、/supplier/offers/{id}/edit）=====
   表单骨架复用 .wb-panel / .merchant-form-grid / .merchant-scenes（列表页表单时代就在用），
   这里只补两块本页专属：图片九宫格与底部操作条。 */
.offer-upload {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 4px
}

.offer-upload-cell {
    position: relative;
    width: 104px;
    height: 104px;
    border: 1px solid #e7e7e7;
    border-radius: 10px;
    overflow: hidden;
    background: #fafafa
}

.offer-upload-cell img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block
}

/* 缩略图右上角的「移除」× 按钮。规格与 .merchant-evidence-remove（merchant-commerce.css）
   逐条一致：20×20 正圆 / rgba(31,35,41,.72) 底 / 白字 13px / hover #c51b21。
   ⚠️ min-height/padding/border 必须显式写 0 并带 !important：commerce.css 有一条
   `body button,[type=button],[type=submit]{min-height:42px;display:inline-flex}` —— min-height 与
   这里的 height 是**两个属性**、不构成覆盖，只写 height:20px 会被撑成 22×42 的椭圆
   （2026-09-24 用户报「叉叉是椭圆的」就是这个）。
   新增同类上传组件请直接给按钮挂 merchant-evidence-remove 类（本块是它的对等实现，别再复制第三份）。 */
.offer-upload-cell button {
    position: absolute;
    right: 3px;
    top: 3px;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 20px !important;
    height: 20px !important;
    min-height: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 50% !important;
    background: rgba(31, 35, 41, .72) !important;
    color: #fff !important;
    font-size: 13px !important;
    line-height: 1 !important;
    cursor: pointer
}

.offer-upload-cell button:hover {
    background: #c51b21 !important
}

.offer-upload-cell em {
    position: absolute;
    left: 4px;
    bottom: 4px;
    padding: 1px 7px;
    border-radius: 5px;
    background: rgba(231, 39, 45, .92);
    color: #fff;
    font-size: 11.5px;
    font-style: normal;
    font-weight: 700
}

.offer-upload-add {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 104px;
    height: 104px;
    border: 1px dashed #d7d7d7;
    border-radius: 10px;
    background: #fafafa;
    color: #9a9a9a;
    font-size: 12.5px;
    cursor: pointer
}

.offer-upload-add i {
    font-style: normal;
    font-size: 20px;
    line-height: 1
}

.offer-upload-add em {
    color: #b9b9b9;
    font-size: 11.5px;
    font-style: normal
}

.offer-upload-add:hover {
    border-color: #ffc9c4;
    background: #fff7f7;
    color: #e7272d
}

.offer-edit-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid #f0f0f0
}

.offer-edit-actions button {
    height: 42px;
    padding: 0 22px;
    border: 1px solid #e3e3e3;
    border-radius: 9px;
    background: #fff;
    color: #444;
    font-size: 14.5px;
    font-weight: 700;
    cursor: pointer
}

.offer-edit-actions button:hover {
    border-color: #ffc9c4;
    color: #e7272d
}

.offer-edit-actions button.primary {
    border-color: transparent;
    background: linear-gradient(135deg, #ff6b5b, #e7272d);
    color: #fff
}

.offer-edit-actions button.primary:hover {
    color: #fff;
    filter: brightness(1.04)
}

.offer-edit-actions button[disabled] {
    opacity: .6;
    cursor: not-allowed
}

.offer-edit-actions a {
    color: #777;
    font-size: 14px;
    font-weight: 600
}

.offer-edit-actions a:hover {
    color: #e7272d
}

@media (max-width: 640px) {
    .offer-upload-cell,
    .offer-upload-add {
        width: 88px;
        height: 88px
    }
}

/* ===== 列表区域高度保底（2026-09-24 用户报「查询会跳到页面头部」，要求全局修）=====
   根因：工作台各列表页的筛选 / 查询 / 翻页都是「就地重渲染」（只换列表容器 innerHTML）。
   结果变少时页面跟着变短，浏览器随即把 window.scrollY 夹到新的最大值 —— 内容越少夹得越狠，
   最狠就是夹到 0，用户看到的就是「一查询就跳到页面头部」。
   ⚠️ 单靠滚动补偿修不了：目标位置超出新的最大滚动距离时会被浏览器夹回原处（实测）。
   所以这里给列表区域一个高度下限：结果少时留白而不是整页塌陷，页面高度不再骤减，
   用户的位置基本稳住；配合 ui.js 的 GRUI.keepScroll（渲染前后补锚点位移）效果最好。 */
.wb-panel .wb-table,
.wb-panel .od-cards,
.wb-panel .merchant-offers,
.wb-panel .merchant-reviews {
    min-height: 46vh
}

/* 空态/加载态在容器里垂直居中，留白不至于全堆在底部。
   ⚠️ flex-direction: column 不能少：空态现在是「图标 + 文案」两个块（.wb-empty::before），
   row 会把图标与文字并排。 */
.wb-panel .wb-table>.wb-empty,
.wb-panel .od-cards>.wb-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 42vh
}
